逆波兰表达式又称为“后缀表达式”。例:4.99*1.06+5.99+6.99*1.06 的后缀表达式为 4.99 1.06 *5.99 +6.99 1.06 +正常写的表达式又称为中缀表达式,如何将一个中缀表达式表达式转换成后缀表达式?这里就要用到栈。但见到一个数时就把他推入栈中,在遇到一个运算符时就将该运算符作用于该栈弹出的两个数(符号)上,将说得结果推入栈中。
举个例子:6 5 2 3 + 8 * +3 *
①前四个字符放入栈中为:6 5 2 3;
②读到一个+号,2 3 出栈执行+法,结果5在压入栈中,栈中元素为:6 5 5;
③8进栈,栈中元素为:6 5 5 8,读入*,5 8出栈执行运算,结果返回栈,栈中元素:6 5 40
④以此类推,最后栈中元素为288,结果也就为288。
现在要求实现:计算带有括号()的表达式的值,例如:32+76+(29+52*(76-24)-14)/12
思路:
1、使用两个栈,一个数据栈,一个操作符栈。当读到一个操作数时,立即将他放入数据栈中,将操作符放入操作符栈中;
2、如果遇到一个左括号,直接压入操作符栈中;
3、如果遇到右括号弹出操作符栈中的操作符直到弹出左括号为止;
4、如果压入的操作符的优先级较高,那么弹出栈中栈顶元素优先级比他高的,知道遇到比他低的为止;
5、最后若字符栈为空,则结束。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//设置运算符的优先级
int level(char op)
{
int x;
switch(op)
{
case '@': x=-1;break;
case '(': x=0;break;
case '+':
case '-': x=1;break;
case '*':
case '/': x=2;break;
}
return x;
}
//计算值
int cal(int x, int y, char op)
{
int result;
switch(op)
{
case '+': result=x+y;break;
case '-': result=x-y;break;
case '*': result=x*y;break;
case '/': result=x/y;break;
}
return result;
}
//计算表达式
int compute(char s[])
{
int y,v1,v2,i;
char ops[100]; //定义运算符栈
int vas[100]; //定义数字栈
int otop,vtop; //定义栈顶指针
otop=vtop=-1;
y=0;
ops[++top]='@';
//遍历整个字符串
while(s[i])
{
if(s[i]=='(') //如果是左括号直接进栈
ops[++top]='(';
else
{
if(s[i]>'0'&& s[i]<'9')
{ //如果是数字转换成int型
while(s[i]>'0'&& s[i]<'9')
{
y=y*10+(s[i++]-48);
}
vas[++top]=y;
i--;
}
}
else
{
if(s[i]=='+'||s[i]=='-'||s[i]=='*' ||s[i]=='/' )
{
//如果栈顶运算符的优先级大于s[i]的优先级,出栈进行计算操作
while(level[s[i]]<level[ops[otop]])
{
op=ops[otop--]; //运算符出栈
v1=vas[vtop--];
v2=vas[vtop--]; //数据出栈
vas[++top]=cal(v1,v2,op); //计算后的数据在进栈
}
//否则直接进栈
ops[++top]=s[i];
}
}
else //如果是右括号
{
if(s[i]==')')
{
//将左括号内的运算符都出栈
while(ops[otop]!='(')
{
op=ops[otop--]; //运算符出栈
v1=vas[vtop--];
v2=vas[vtop--]; //数据出栈
vas[++top]=cal(v1,v2,op); //计算后的数据在进栈
}
otop--; //左括号出栈
}
}
i++;
}
//字符串遍历完,栈中可能还有运算符
while(otop!=0)
{
op=ops[otop--]; //运算符出栈
v1=vas[vtop--];
v2=vas[vtop--]; //数据出栈
vas[++top]=cal(v1,v2,op); //计算后的数据在进栈
}
return vas[vtop];
}
//主函数
int main()
{
char s[100];
int value;
gets(s);
value=compute(s);
printf("%s=%d",s,value);
}