读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2 4 + 2 * 5 - 7 / 11 0
Sample Output
3.00 13.36
解题思路:
https://blog.csdn.net/MM__1997/article/details/78115962
分析:
中缀表达式求值 题目中没有括号 代码里加了括号
首先知道运算符的优先关系
计算方法
设置两个栈 一个符号栈 一个数字栈
初始化符号栈 将一个 "#" 压入占中
将得到的字符串处理为只含有数字和运算符 末尾加入 "#"
扫描处理后的字符串
如果扫描为运算符 将该运算符与符号栈栈顶运算符比较
如果栈顶运算符优先级低于该运算符 该运算符入栈
如果栈顶运算符优先级等于该运算符 托括号操作 弹出栈顶运算符
如果栈顶运算符优先级高于该运算符 从数字栈中弹出两个数字与栈顶运算符运算 将计算结果重新压入数字栈 并将栈顶运算符弹出 该运算符入栈
如果扫描为数字 将数字压入数字栈
最后 数字栈栈顶元素即为结果
王道讲解:
AC代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<stack>
using namespace std;
char str[1010];
char ans[1010][1010];
char *sep=" ";//分隔符
char *p;
double cal(double a,double b,char c)
{
if(c=='+') return a+b;
if(c=='-') return a-b;
if(c=='*') return a*b;
if(c=='/') return a/b;
}
int judge(char p1,char p2)
{
if(p1=='+'||p1=='-')
{
if(p2=='+'||p2=='-'||p2==')'||p2=='#') return 1;
else return -1;
}
else if(p1=='*'||p1=='/')
{
if(p2=='(') return -1;
else return 1;
}
else if(p1=='(')
{
if(p2==')') return 0;
else return -1;
}
else if(p1==')') return 1;
else if(p1=='#')
{
if(p2=='#') return 0;
else return -1;
}
}
int main()
{
while(gets(str))
{
int len=strlen(str);
str[len]=' ';
str[len+1]='#';
stack<char> s1;//符号栈
stack<double> s2;//数字栈
s1.push('#');
p=strtok(str,sep);
int l=0;
memset(ans,0,sizeof(ans));
do
{
strcpy(ans[l++],p);
}while
(
p=strtok(NULL,sep)
);
if(!strcmp(ans[0],"0")&&l==2) break;
int index=0;
while(ans[index][0]!='#'||s1.top()!='#')
{
if(!isdigit(ans[index][0]))//为运算符
{
char temp=s1.top();
int tt=judge(temp,ans[index][0]);
if(tt==-1)
{
s1.push(ans[index][0]);
index++;
}
else if(tt==0)
{
s1.pop();
index++;
}
else if(tt==1)
{
double a=s2.top();
s2.pop();
double b=s2.top();
s2.pop();
s2.push(cal(b,a,s1.top()));
s1.pop();
}
}
else//为运算符
{
s2.push(atof(ans[index]));
index++;
}
}
printf("%.2lf\n",s2.top());
}
return 0;
}