- 用栈求后缀表达式值(把中缀表达式转成后缀表达式,再用栈求值)
从左到右扫描,当遇到操作数的时候就入栈,当遇到运算符的时候就从栈顶弹出两个操作数,结合这个运算符计算结果(注意:第一个弹出的操作数在右边,第二个弹出的操作数在左边),将计算的结果压入栈中,如此进行下去,那么表达式被扫描完之后,整个计算过程也就结束了。
float calPostFix(char exp[]) //float返回值类型
{
float s[maxSize]; int top = -1;
int i=0;
while (exp[i] != '\0') //for(int i=0;exp[i]!='\0';++i)
{
if ('0'<=exp[i] && exp[i]<='9') //判断字符是否是数字
s[++top]=exp[i]-'0'; //将字符型数字转化成数值型数字的方法
else if (exp[i] == '+' ||
exp[i]=='-' ||
exp[i]=='*' ||
exp[i] == '/') //可直接省略成else
{
float opnd1,opnd2,result;
char op;
int flag;
opnd2=s[top--]; //第二个操作数先出栈
opnd1 = s[top--];//第一个操作数后出栈
op=exp[i];
flag = calSub(opnd1,op,opnd2,result);
if (flag == 0){ //计算失败
{
std::cout<<"ERROR"<<std::endl; //puts("ERROR");
break;
}
s[++top]=result;
}
++i;
}
return s[top];//没有栈中元素剩余的情况,直接返回结果
}
- 用栈求前缀表达式值
这个过程就和求后缀表达式值非常类似,只不过是在很多方面上体现了一个相反的过程。具体就是需要从右往左扫描,遇到操作数就让它入栈,遇到运算符就出战两个操作数,不同的是这次我们构造子表达式的时候,是先出栈的操作数在左边,后出栈的操作数在右边(先出栈的数与扫描方向一致),其他的就和后缀式求值没什么区别了。
求前缀式值后缀式值比求中缀式值简单,前者只需要一个栈且不需要考虑括号,后者需要两个栈且需要考虑括号,把后者转化成前者就是因为求值简单且节省空间
float calPreFix(char exp[],int len) //float返回值类型
{
float s[maxSize]; int top = -1;
int i=len-1;
while (i>=0) //for(int i=len-1;i>=0;--i)从右往左扫描
{
if ('0'<=exp[i] && exp[i]<='9') //判断字符是否是数字
s[++top]=exp[i]-'0'; //将字符型数字转化成数值型数字的方法
else if (exp[i] == '+' ||
exp[i]=='-' ||
exp[i]=='*' ||
exp[i] == '/') //可直接省略成else
{
float opnd1,opnd2,result;
char op;
int flag;
opnd1=s[top--]; //第二个操作数先出栈
opnd2=s[top--];//第一个操作数后出栈
op=exp[i];
flag = calSub(opnd1,op,opnd2,result);
if (flag == 0){ //计算失败
{
std::cout<<"ERROR"<<std::endl; //puts("ERROR");
return 0;
}
s[++top]=result;
}
--i;
}
return s[top];//没有栈中元素剩余的情况,直接返回结果
}