如何利用堆栈及逆波兰式 四则运算表达式进行数学四则运算

逆波兰表达式解决四则运算
&& 逆波兰表达式又叫做后缀表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式,解决了四则运算中括号改变运算符优先级的问题。
四则运算的表达式一般都是中缀表达式如 1+2*(3-4)+5,即操作符在两个操作数之间。四则运算需要两个步骤,一是把中缀表达式转为后缀表达式,二是由后缀表达生成结果
中缀表达式转为后缀表达式算法描述:
(1)首先有个包含中缀表达式元素列表sourceList,然后创建一个符号列表destList保存最终后缀表达式,创建一个操作符堆栈opStack
(2)从sourceList取出一个元素A
(3a)如是数字则加入到destList中
(3b)如果元素A是运算符,将操作符A与操作符堆栈opStack栈顶的运算符的优先关系相比较。如果,优先关系高于opStack栈顶的运算符,则将该运算符压入操作符堆栈opStack。倘若不是(低于或等于)的话,则将运算符栈opStack栈顶的运算符从栈中弹出保存到destList,重复此步骤,直到作符A压入操作符堆栈opStack。
(3c)若元素A是左括号&(&,则压入操作符堆栈opStack
(3d)若元素B是右括号&)&,则操作符堆栈opStack弹出操作符并加入到destList中,直到弹出左括号&(&。
(5)从步骤2重复上述操作,所有元素处理完毕后将操作符堆栈opStack弹出操作符并加入到destList中,这样中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
中缀表达式如 1+2*(3-4)+5,构造元素列表1,+,2,*,(,3,-,4,),5,构造一个空最终后缀表达式destList,一个操作符堆栈opStack
1、取出“1”,destList【1】,opStack【】
2、取出“+”,destList【1】,opStack【+】
3、取出“2”,destList【1,2】,opStack【+】
4、取出“*”,destList【1,2】,opStack【+,*】
5、取出“(”,destList【1,2】,opStack【+,*,(】
6、取出“3”,destList【1,2,3】,opStack【+,*,(】
7、取出“-”,destList【1,2,3】,opStack【+,*,(,-】
8、取出“4”,destList【1,2,3,4】,opStack【+,*,(,-】
9、取出“)”,destList【1,2,3,4,-】,opStack【+,*】& //操作符堆栈opStack弹出操作符并加入到destList中,直到弹出左括号&(&
10、取出“+”,destList【1,2,3,4,-,*,+】,opStack【+】 //加号优先级不大于【+,*】
11、取出“5”,destList【1,2,3,4,-,*,+,5】,opStack【+】
12、处理完毕,destList【1,2,3,4,-,*,+,5,+】,opStack【】
后缀表达式到计算结果算法描述:
遍历储存后缀表达式的列表,将元素依次进栈,当遇到操作符时,连续出栈两个元素,进行运算,再将结果进栈,最后栈内留下的元素就是计算结果
后缀表达式destList【1,2,3,4,-,*,+,5,+】,结果堆栈resultStatck【】
输入--&:结果
[1,2,3,4]--&:resultStatck【1,2,3,4】
[-]--&:resultStatck【1,2,3-4】
[ * ]--&:resultStatck【1,2*(3-4)】
[+]--&:resultStatck【1+2*(3-4)】
[5]--&:resultStatck【1+2*(3-4),5】
[+]--&:resultStatck【1+2*(3-4)+5】
系统分类:&>>&数据结构练习题 004 栈 逆波兰表达式的计算_C++,C语言_ThinkSAAS
数据结构练习题 004 栈 逆波兰表达式的计算
数据结构练习题 004 栈 逆波兰表达式的计算
数据结构练习题 004 栈 表达式的计算——逆波兰用联合表达栈元素,是懒,不想写2次栈的实现代码。以空间换时间。
ExprStack.h
#ifndef EXPRSTACK_H
#define EXPRSTACK_H
#define DEFAULTSTACKSIZE
#define STACKINCREMENT
typedef union element_type_tag
} ELEMENTTYPE;
typedef struct stack_operator_tag
ELEMENTTYPE *
} STACKEXPR;
STACKEXPR *CreateStack(void);
void DestroyStack(STACKEXPR *p);
int PushElement(STACKEXPR *p, ELEMENTTYPE d);
int PopElement(STACKEXPR *p, ELEMENTTYPE *d);
int GetTopElement(STACKEXPR *p, ELEMENTTYPE *d);
ExprStack.c
#include &stdlib.h&
#include "ExprStack.h"
* 创建空栈
* 参数:无
* 返回值:栈指针
STACKEXPR *CreateStack(void)
STACKEXPR *p;
p = (STACKEXPR *)malloc(sizeof(STACKEXPR));
if(p == NULL)
return NULL;
p-&base = (ELEMENTTYPE *)malloc(sizeof(ELEMENTTYPE)*DEFAULTSTACKSIZE);
if(p-&base == NULL)
return NULL;
p-&top = 0;
p-&size = DEFAULTSTACKSIZE;
* 参数:p 栈指针
* 返回值:无
* 细节:释放栈内数据内存和栈内存
void DestroyStack(STACKEXPR *p)
if(p-&base)
free(p-&base);
* 参数:p 栈指针,d 入栈数据
* 返回值:成功返回 1,失败返回 0
* 细节:若栈满,则先增容。压数据入栈
int PushElement(STACKEXPR *p, ELEMENTTYPE d)
if(p == NULL || p-&base == NULL)
//栈满则增容
if(p-&top &= p-&size)
p-&base = (ELEMENTTYPE *)realloc(p-&base,
sizeof(ELEMENTTYPE)*(p-&size + DEFAULTSTACKSIZE));
if(p-&base == NULL)
p-&size += DEFAULTSTACKSIZE;
*(p-&base + p-&top) =
* 参数:p 栈指针,d 存放出栈数据的地址
* 返回值:成功返回 1,失败返回 0
int PopElement(STACKEXPR *p, ELEMENTTYPE *d)
if(p == NULL || p-&base == NULL || d == NULL || p-&top &= 0)
*d = *(p-&base + p-&top);
* 取栈顶元素值
* 参数:p 栈指针,d 存放栈顶数据的地址
* 返回值:成功返回 1,失败返回 0
int GetTopElement(STACKEXPR *p, ELEMENTTYPE *d)
if(p == NULL || p-&base == NULL || d == NULL || p-&top &= 0)
*d = *(p-&base + p-&top - 1);
ExprString.h
#ifndef EXPRSTRING_H
#define EXPRSTRING_H
int Infix2suffix(char *t, char *s);
int CalSuffix(char *s, double *r);
ExprString.c
#include &stdlib.h&
#include &string.h&
#include "ExprStack.h"
#include "ExprString.h"
int GetOptrLvl(char c);
int GetType(char c);
int Operate(double a, char c, double b, double *r);
* 判断字符类型
* 参数:c 字符
* 返回值:空格 5,左括号 4,右括号 3,运算符 2,数 1,其他 0
int GetType(char c)
if(c == & &)
else if(c == &(&)
else if(c == &)&)
else if(c == &+& || c == &-& || c == &*& || c == &/&)
else if((c &= &0& && c &= &9&) || c == &.&)
* 取得运算符等级
* 参数:c 字符
* 返回值:乘除 5,加减 3,左括号 1,其他 0
int GetOptrLvl(char c)
* 计算结果
* 参数:a b 操作数,c 操作符,r 计算结果
* 返回值:有效计算返回 1,无效计算返回 0
int Operate(double a, char c, double b, double *r)
if(b != 0)
//这里没有 break ,顺着 default 返回 0
* 中缀表达式转后缀表达式
* 参数:t 目标后缀表达式,s 源中缀表达式
* 返回值:成功 1,失败 0
* 细节:t 必须空间充足,后缀表达式各元素间以 空格 分割
int Infix2suffix(char *t, char *s)
STACKEXPR *p;
ELEMENTTYPE
int len, i,
if(!t || !s || (len = strlen(s)) & 1 || !(p = CreateStack()))
for(i=0; i& i++)
switch(GetType(s[i]))
//右括号:栈顶出栈,直至匹配到左括号
while(PopElement(p, &c) && c.optr != &(&)
*t++ = & &;
//操作符:+ - * /
//本操作符等级不高于栈顶操作符,出栈
while(GetTopElement(p, &c) && GetOptrLvl(s[i])&=GetOptrLvl(c.optr))
PopElement(p, &c);
*t++ = & &;
//这里没有 break,顺着直接进栈
//左括号:直接进栈
c.optr = s[i];
if(PushElement(p, c) == 0) goto ERROR;
//数字:直接进后缀表达式
*t++ = s[i++];
} while(GetType(s[i]) == 1);
// i 加多了一次,回退 1
*t++ = & &;
//空格:忽略
//非法字符
goto ERROR;
//栈内剩余操作符全部出栈
while(PopElement(p, &c))
if(c.optr == &(&) goto ERROR;
*t++ = & &;
DestroyStack(p);
DestroyStack(p);
* 计算后缀表达式的值
* 参数:s 后缀表达式, r 存放结果
* 返回值:成功 1,失败 0
int CalSuffix(char *s, double *r)
STACKEXPR *p;
ELEMENTTYPE
double a, b,
char t[256] = "";
int len, i,
if(!r || !s || (len = strlen(s)) & 1 || !(p = CreateStack()))
for(i=0; i& i++)
switch(GetType(s[i]))
//数字直接进栈
t[j++] = s[i++];
} while(GetType(s[i]) == 1);
t[j] = &&;
c.opnd = atof(t);
if(PushElement(p, c) == 0) goto ERROR;
//符号:计算
if(PopElement(p, &c) == 0) goto ERROR;
if(PopElement(p, &c) == 0) goto ERROR;
if(Operate(a, s[i], b, &ab) == 0) goto ERROR;
if(PushElement(p, c) == 0) goto ERROR;
//忽略空格
goto ERROR;
//取结果值
if(PopElement(p, &c) == 0) goto ERROR;
DestroyStack(p);
DestroyStack(p);
#include &stdio.h&
#include "ExprStack.h"
#include "ExprString.h"
int main(int argc, char *argv[])
char infix[] = "9.1+7.5*8/4-7.9*(18/3-4)+(1.5*8+1.6)/7-8.4";
//中缀表达式
char suffix[1024];
//后缀表达式
//计算结果
printf("n infix = %s", infix);
if(Infix2suffix(suffix, infix))
printf("n suffix = %s", suffix);
if(CalSuffix(suffix, &r))
printf("n result = %g n", r);
printf("n Error : CalSuffixn");
printf("n Error : Infix2suffixn");
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信下次自动登录
现在的位置:
& 综合 & 正文
如何利用堆栈及逆波兰表达式进行数学四则运算(C语言版)
本文演示如何利用自定义堆栈(可实现通用性)和逆波兰表达式(后缀表达式)来进行数学四则运算。
阅读须知:了解堆栈定义过程、了解中缀表达式、了解后缀表达式(逆波兰表达式)。不清楚的同学百度一下,用10分钟了解一下即可。
示例优点:
1,自己做了一些注释, 尽量将转换原理和计算原理说清一些,如果还有看不明白的同学,只好移步百度谷歌了。
2,自己定义了一个堆栈,可实现数据类型无关性。简称通用性堆栈。参考:/kf/64.html
3,基于以上两点,以后大家如需将中缀表达式转换为后缀表达式或者需使用通用性堆栈,可直接使用示例中的源码。
1,没做什么优化,对用户输入也没有严格验证。
注:做一个利用堆栈及逆波兰表达式进行数学四则运算的小程序,一方面方便自己以后查看使用。另一方面,也希望抛砖引玉,大家一起来探寻更好的计算方法。
#include &stdio.h&
#include &stdlib.h&
#include &string.h&
#define TRUE 1
#define FALSE 0
#define ERROR -1
#define STACKELEMENT 100 //定义堆栈中可入栈元素个数
#define BUFFERSIZE 100
//定义临时缓冲区大小
typedef int S //定义返回状态
typedef struct
//定义堆栈:堆栈中只定义栈大小和每次入栈元素大小,栈中一律使用空指针进行操作。这样,我们自己定义的栈就做到了和数据类型无关性。真正实现了栈的通用。
void * //指向栈底
//指向栈顶
int stackS //栈的空间总容量大小
int typeS //入栈时,单个元素占用空间大小
Status InitStack(sqStack *s,unsigned stackSize,unsigned typeSize); //初始化栈
Status Push(sqStack *s,void *e); //入栈
Status Pop(sqStack *s,void *e); //出栈
Status ClearStack(sqStack *s); //清空栈内所有元素
Status DestroyStack(sqStack *s); //销毁栈
int GetLen(sqStack *s); //获取已入栈元素个数
Status Calculate(char *arr,void *result); //计算表达式结果:参数一:arr为使用空格分隔的采用后缀表达式表示的要计算的字符串,例:arr={"3 5 + "}。参数二:result存放计算结果。
Status InfixToPostfix(char *infix,char *postfix); //将中缀表达式转换为后缀表达式。例:infix={"3+5\n"} ,转换后,postfix={"3 5 + "};
void my_err(char *str); //自定义错误处理函数
int main(int argc,char *argv[])
printf("Please input the nifix expression.\n"); //输入中缀表达式。
char src[BUFFERSIZE]={'\0'}; //存放中缀表达式的临时缓冲区
char *infix=
char postfix[BUFFERSIZE]={'\0'}; //存放后缀表达式的临时缓冲区
fgets(infix,BUFFERSIZE,stdin); //从标准输入流中读取要计算的四则运算表达式
printf("Infix expression:%s",infix);
InfixToPostfix(infix,postfix); //将中缀转换为后缀表达式
printf("Postfix expression:%s\n",postfix);
Calculate(postfix,&result); //计算后缀表达式的结果
printf("result:%f\n",result);
将中缀表达式转换为后缀表达式
参数:infix 指向中缀表达式,以回车键即\n结尾。
postfix 指向后缀表达式临时缓冲区,用来存放转换后的结果。
附转换规则:从左到右遍历中缀表达式的每个数字和符号,若是数字则直接保存在postfix数组中;若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级不大于栈顶符号,则栈顶元素依次出栈并输出,直到遇到左括号或者栈空时,才将刚才的那个符号入栈。
Status InfixToPostfix(char *infix,char *postfix)
if(InitStack(&s,STACKELEMENT*sizeof(char),sizeof(char))==ERROR)
my_err("InfixToPostfix init stack error!");
int j=0,i=0;
c=*(infix+i); //取出中缀表达式中的第一个字符
while('\n'!=c) //遇到换行符,表示转换结束
while(c&='0'&&c&='9') //先判断一下取出的字符是否是数字,如果是数字的话,则直接存入postfix数组
postfix[j++]=c;
c=*(infix+i);
if(c&'0'||c&'9') //如果不是数字,则在后面添加空格,以便区分各个符号
postfix[j++]=' ';
if(')'==c) //不是数字,则判断是否为右括号。[括号的优先级最高,所以,如果是右括号的话,就得先进行括号里的各种运算]
Pop(&s,(void*)&e);
while('('!=e) //直到遇到左括号为止
postfix[j++]=e;
postfix[j++]=' ';
Pop(&s,(void*)&e);
else if('+'==c||'-'==c) //如果是加减号,因为他俩的优先级最低了,所以此时先将栈里的所有符号出栈后(除非遇到左括号),再把此符号入栈
if(!GetLen(&s)) //如果是空栈,则直接将加减号入栈
Push(&s,(void*)&c);
Pop(&s,(void*)&e);
if('('==e)
Push(&s,(void*)&e);
postfix[j++]=e;
postfix[j++]=' ';
}while(GetLen(&s)&&'('!=e);
//将栈里的所有符号出栈(除非遇到左括号)
Push(&s,(void*)&c); //最后将新来的加减号再入栈
else if('*'==c||'/'==c||'('==c) //如果是乘除号或左括号,因为他们的优先级高,所以直接入栈。
Push(&s,(void*)&c);
else if('\n'==c) //判断一下,所有符号是否都已转换完成
else //能走到这个else的,都是我不认识的符号了
// printf("\nError:input error,the character %d cann't recognize!\n",c);
return -1;
c=*(infix+i); //取出下一个字符进行转换
while(GetLen(&s)) //转换完成后,栈里可能还有没出栈的运算符号
Pop(&s,(void*)&e);
postfix[j++]=e;
postfix[j++]=' ';
DestroyStack(&s);
return TRUE;
计算后缀表达式的结果
参数:arr使用空格分隔的后缀表达式字符串。例:arr="31 5 + "
result 保存计算完毕后的结果
注:如何利用栈来计算后缀表达式的结果:依次取出后缀表达式中的符号进行比较,如果是数字,则直接入栈;如果是符号,则出栈两次,弹出两个要计算的因数,进行计算,之后再将计算结果入栈。知道后缀表达式中所有符号都已比较完毕。
Status Calculate(char *arr,void *result)
// printf("%s\n",arr);
double d,e,f; //d,e 存放两个因数。f存放d,e计算后的结果.
char * //存放后缀表达式中的每个因数或运算符
char *buf= //声明bufhe saveptr两个变量,是strtok_r函数的需要。
char *saveptr=NULL;
if(InitStack(&s,STACKELEMENT*sizeof(double),sizeof(double))==ERROR)
my_err("Calculate init stack error!");
while((op=strtok_r(buf," ",&saveptr))!=NULL) //利用strtok_r函数分隔字符串
switch(op[0])
Pop(&s,&d);
Pop(&s,&e);
Push(&s,&f);
Pop(&s,&d);
Pop(&s,&e);
Push(&s,&f);
Pop(&s,&d);
Pop(&s,&e);
Push(&s,&f);
Pop(&s,&d);
Pop(&s,&e);
Push(&s,&f);
d=atof(op); //不是运算符,就肯定是因数了。所以,用atof函数,将字符串转换为double类型
Push(&s,&d);
Pop(&s,result);
DestroyStack(&s);
return TRUE;
参数:stackSize:栈的总容量大小
typeSize:以后要入栈的单个元素的大小
Status InitStack(sqStack *s,unsigned stackSize,unsigned typeSize)
s-&base=malloc(stackSize);
if(!s-&base)
return ERROR;
s-&top=s-&
s-&stackSize=stackS
s-&typeSize=typeS
return TRUE;
Status Push(sqStack *s,void *e)
if((int)s-&top-(int)s-&base+s-&typeSize&s-&stackSize)
return FALSE;
memcpy(s-&top,e,s-&typeSize);
s-&top=(void*)((int)s-&top+s-&typeSize);
return TRUE;
Status Pop(sqStack *s,void *e)
if(s-&top==s-&base)
return FALSE;
s-&top=(void*)((int)s-&top-(int)s-&typeSize);
memcpy(e,s-&top,s-&typeSize);
return TRUE;
Status ClearStack(sqStack *s)
s-&top=s-&
return TRUE;
Status DestroyStack(sqStack *s)
free(s-&base);
s-&top=s-&base=NULL;
s-&stackSize=s-&typeSize=0;
return TRUE;
获取已入栈元素个数
int GetLen(sqStack *s)
return ((int)s-&top-(int)s-&base)/s-&typeS
自定义错误处理函数
void my_err(char *str)
perror(str);
示例运算:
&&&&推荐文章:
【上篇】【下篇】逆波兰式到底是什么鬼 ?
百度百科上讲,逆波兰式更适合计算机运算。那么逆波兰式到底是什么鬼?在c++中计算a+b时,输入ab+显然是错误的,那么是不是编译*系统编译给机器的就是ab+呢?如果不是,那么逆波兰式到底怎么应用?
按时间排序
逆波兰式又叫后缀表达式。
1.人类的a+b叫做中缀表达式,当人类发明了计算机后,想通过计算机来计算式子。
2.可是数学已经发展很久了,一些事实例如(先算括号里面的,再乘除后加减),如果直接写入计算机它是不能像人类一样知道先算括号再怎样怎样的。
3.一个聪明的波兰人就想出了后缀表达式。3+2*(5-7)/4
计算机先会把它转化成逆波兰式然后通过栈求解。怎么转,每一本数据结构都有
”逆波兰式”也叫“后缀表达式”先放着。回头再来填坑。
刚好这几天看了点Bjarne老爷爷的书,上面有点有关的内容,强答一下。一个式子,可以分成几个层面来看。比如1 + 2 * 3,我们看它是个算式,计算机看它,那就是个字符串,所以首先必须把它拆分成计算机可以操作的数据单元,就是Tokenize。比如1 2 3是操作数,+ 和*是操作符。但是这还不够,算式有优先级之分,先算乘除,后算加减,也就是算式这种人类描述数学式子的语言,有其自身的文法,所以对于一个算式,我们还得对这个式子再做分析,就是Parser。人类发明的语言,计算机分析起来麻烦点,因为计算机处理字符串是从左到右流式的,不像人,先看看后面再看看前面都可以。比较适合计算机处理的是什么样的呢?先看看波兰表达式。一般来说,加减乘除四种运算可以看成是二对一的函数关系:两个数加减乘除以后得到一个数。如果把运算符放在前面,比如(+ 1 2),就可以看做“+”这个操作作用在1和2上。Lisp就是这样做的。这样有个好处,比如多个数相加的时候,就可以写(+ 1 2 3 4 ),而括号内的东西也可以看成一个整体。复杂一点的式子(+ (* 2 3) (/ 5 6) )从括号就能看出各项的层级关系。逆波兰表达式更适合从左到右扫描了。(a + b) * c的逆波兰表达式是a b + c *,括号都不用就把优先级的问题解决了。
所谓“逆波兰式”指的是后缀表达法。举个很贴近的例子,中文和日语的语法,日语的动词是在句末:中文:我爱你日语:我你爱你跟日本人用日语沟通,却用中文的文法,日本人懂吗?懂,但是很憋屈,因为要转换思维,要解析。同样的道理,计算机并非解决不了我们平时用的中缀表达式,而是我们用程序语言写下来太麻烦,要加以多重逻辑判断,才能解析一条算式。然而基于栈的数据结构,用“逆波兰式”只需控制简单流程,算式转换为“逆波兰式”也只需要用到简单的数据结构,这样我们能够不假思索的写程序。可能我说的没什么感觉,在举个例子,你和一个土著人语言不通,那怎么沟通?可以用肢体语言,总会能让他明白(只要他不吃了你)。突然有一天,你发现把话反过来说,土著人就能听明白了,虽然对你而言,这样说话很憋屈,但明显比肢体语言。在你造了一个能把你说的话自动反过来的机器以后,从此你就只需要正常说话就好了。你看,完全不需要复杂的逻辑,只需要控制流程就能完成一件复杂的事。
========================================================强烈要求知乎加入绘图,GIF和Markdown语法支持========================================================逆波兰表达式是一种利用栈来进行运算的数学表达式。以一个表达式 1 + 2 * 3 为例。以顺序方式输入这个表达式,计算机首先需要解析这个表达式,然后递归的求值。比如从左起进行顺序解析,得到一个符号树:
3计算机会递归的从叶子开始求值,最后回到根,得出结果。所以对于一个比较复杂的表达式,树可能会很深,而且递归的过程将会消耗大量的内存,由于有解析和运算两个过程,时间开销也不理想。如果将上式改为逆波兰表达式: 3 2 * 1 +那么就能实现 “在线处理”。在线处理必须是这类问题在计算机中最快的算法。还是从左侧开始,扫描这个表达式。扫描到第一项,为一个操作数,那么可以把这个数压栈,然后继续扫面。3第二项还是一个操作数,同样的压栈继续。23到第三项,得到一个双目运算符,这时候计算机就从操作数栈中弹出两个数作为运算符的两个参数,然后进行运算,并将结果再压回操作数栈。6接着第四项,一个操作数,压栈。第五项,又是一个双目运算符,那么弹出两个操作数进行运算,把结果压栈。16到此,这个表达式就扫描结束了,操作数栈中最后会剩下表达式的运算结果。7不需要两次操作,只要从头扫描到尾就能求出结果,也不需要递归,只需要一个很小的栈就可以。所以逆波兰表达式算法取得了时间复杂度和空间复杂度上的双重优势。并且:从左到右扫描,有运算符就运算,对于复杂的表达式,不容易出错;栈可以自动的记录中间结果;机器只需要维护一个操作数堆栈,栈中只有操作数和结果所以在机器上实现起来非常的方便。早期,处理器性能比较弱的时候,使用这种方式就可以在性能不足的机器上实现任意复杂度的表达式运算。很棒吧。至于你的问题,主要是在于“为啥我的汽车不能飞”,很简单,因为不支持。使用一种软件的时候需要按照软件提供的功能来操作,编程语言也是一种软件系统,如果你想在这里面使用逆波兰表达式,那么需要软件提供对逆波兰表达式的支持。对于编程语言,就是语法级的支持。编译器在编译时怎么实现的我没有研究过。但是对于常数值,在编译时就可以确定,对于变量,我想还是和平台相关吧。对于寄存器比较少的平台,有可能会把表达式的运算序列化成一个逆波兰表达式。只是有可能,没有研究过编译器的实现。应用主要是任何基于栈的程序语言,计算机(相当大一部分工程计算机都是基于栈的)。
维基百科已经说得很清楚了,看完就基本可以明白了
试试 postscript 或者 forth
hdu 1237题主可以去做下这个题目,你大概就知道,你想的和计算机想的其实是不一样的。
a+b是给人看的,编译器把它变成ab+,给执行器(vm之类)看,因为它很容易转换成栈虚拟机模型的代码:load aload baddpop
珍爱智商,远离(百度)百科。没别人回答我再解释……
已有帐号?
无法登录?
社交帐号登录用堆栈实现算术表达式转换至逆波兰表达式(C++)_百度知道}

我要回帖

更多关于 逆波兰式 四则运算 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信