Q:读入一个只包含+-*/的非负整数计算表达式,计算该表达式的值。
样例输入:4+2*5-7/11
分析:利用堆栈对表达式求值是数据结构中典型的例子,算法分析如下:
1.设立两个堆栈,一个存储运算符,一个存储数字
2.表达式首尾添加标记运算符,且此运算符优先级最低。
3.从左到右遍历表达式,若为数字,则压入数据栈。
4.若为运算符,则与栈顶运算符进行优先级比较,如果当前运算符优先级高于(不低于)栈顶运算符,则当前运算符压入运算符栈;反之,则弹出栈顶运算符,同时连续弹出数字栈顶数字两次,计算后将结果压入数字栈,将当前运算符压入运算符栈。
5.重复3,4步,直到遇到标志运算符。
代码如下:
#include<stdio.h>
#include<stack>
#include<string>
#include<stdlib.h>
#define optsize 6
using namespace std;
char opt[optsize]={'+','-','*','/','#','='};//运算符集
int optcmp[optsize][optsize]=
{1,1,0,0,1,1,
1,1,0,0,1,1,
1,1,1,1,1,1,
1,1,1,1,1,1,
0,0,0,0,0,0,
0,0,0,0,0,0};//运算符比较结果,若小于则为0
bool judgeopt(char c)
{
bool result=false;
for(int k=0;k<optsize;k++)
{
if(c==opt[k]) result=true;
}
return result;
}//判断是否为运算符
int rnt(char c)
{
for(int i=0;i<optsize;i++)
{
if(c==opt[i])
return i;
}
return 0;
}//返回运算符下标
double calculate(double a,double b,char c)
{
switch(c)
{
case '+':return a+b;break;
case '-':return a-b;break;
case '*':return a*b;break;
case '/':return a/b;break;
default: return 0;
}
}
int rnt_optcmp(int a,int b)
{
return optcmp[a][b];
}//返回比较结果
int main()
{
char str[100];
char c;
stack<double> sopd;
stack<char> sopt;
while(!sopd.empty()) sopd.pop();
sopt.push('#');
while(scanf("%s",str)!=EOF)
{
for(int j=0;str[j]!='='||sopt.top()!='#';j++)//**控制循环的关键**
{
c=str[j];
if(!judgeopt(c))//如果不是运算符
{
double data=c-'0';//******************把数字字符转换为其表示的数字,再压入数字栈**************
sopd.push(data);
}
else
{
if(rnt_optcmp(rnt(c),rnt(sopt.top()))==1)//c优先级大于栈顶运算符
{
sopt.push(c);
}
else
{
double c_a=sopd.top();
sopd.pop();
double c_b=sopd.top();
sopd.pop();
double c_c=calculate(c_b,c_a,sopt.top());
sopd.push(c_c);
sopt.pop();
if(c!='=')//若为'=',注意不要压入栈
{
sopt.push(c);
}
else j--;//*************使str[j]停留在‘=’这里,省去对str[]的'='初始化。(小技巧)**********
}
}
}
printf("%lf",sopd.top());
}
return 0;
}
来源:http://www.cnblogs.com/fengshitianshi/archive/2013/03/29/2989511.html