Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
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/u014532901/article/details/52524624#代码示例
AC代码:
//表达式求值
#include <iostream> #include<cstdio> #include<stack> #include<cstring> using namespace std; char s[1010]; int getnum(int i,int j){ if(i>j) return -1; int ret=0; for(int k=i;k<=j;k++){ if(s[k]!=' ') ret=ret*10+(s[k]-'0'); } return ret; } int cmp(char a,char b){//若a的优先级大于等于b,返回1,否则返回-1 if(a=='*'||a=='/') return 1; else if(a=='+'||a=='-'){ if(b=='*'||b=='/') return -1; else return 1; } else{ if(b=='#') return 1; else return -1; } } 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*1.0/(b*1.0); return 0; } int main() { while(gets(s)){ int len=strlen(s); if(len==1&&s[0]=='0') break; s[len]='#';//保证了计算结束后操作符栈中只剩一个'#' stack<double> stk_digits; stack<char> stk_operator; for(int i=0,j=0;i<=len;){ if(s[i]==' '||(s[i]>='0'&&s[i]<='9')) i++; else{ int num=getnum(j,i-1);//将s[j~i-1]这一段字符串转为数值 if(num!=-1) {stk_digits.push(num); j=i+1;} if(stk_operator.empty()) {stk_operator.push(s[i]); i++;} else{ if(cmp(stk_operator.top(),s[i])==1) { double tmp2=stk_digits.top(); stk_digits.pop(); double tmp1=stk_digits.top(); stk_digits.pop(); stk_digits.push(cal(tmp1,tmp2,stk_operator.top())); stk_operator.pop(); } else {stk_operator.push(s[i]); i++;} } } } printf("%.2f\n",stk_digits.top()); } return 0; }
对于此题,也可以用不转后缀表达式的方法:
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int main() { double tmp; double num[1010];//因式 while(scanf("%lf",&tmp)!=EOF){ int cnt=0; char c=getchar(); if(tmp==0&&c=='\n') break; memset(num,0,sizeof(num)); num[++cnt]=tmp; if(c=='\n') {printf("%.2f\n",num[cnt]); continue;} char op; double x; while(1){ scanf("%c%lf",&op,&x); if(op=='*') num[cnt]*=x; if(op=='/') num[cnt]/=(x*1.0); if(op=='+') num[++cnt]=x; if(op=='-') num[++cnt]=-x; if(getchar()=='\n') break; } double ans=0; for(int i=1;i<=cnt;i++) ans+=num[i]; printf("%.2f\n",ans); } return 0; }