Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位
Sample Input
1 + 2
4 + 2 * 5 - 7 / 11
0
Sample Output
3.00
13.36
Solution
模拟四则运算过程,对于整个输入的串,遇到数字则提取出来进数字栈,遇到加减运算则进运算符栈,遇到乘除运算则从数字栈中拿出栈顶元素与运算符之后提取出的整数进行运算并将结果进数字栈,这样当枚举完整个串的元素后,我们就得到了一个只有加减运算的表达式,但因为这个表达式在栈中的顺序是反的,所以要再开两个栈来将这个表达式反序,之后就每次从数字栈栈顶取出两元素,从运算符栈中取出一个运算符,将运算结果压进数字栈中,最后数字栈剩下的一个元素即为表达式的最终结果
Code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<stack>
using namespace std;
int main()
{
char s[222];
while(gets(s),strcmp(s,"0"))
{
int len=strlen(s);
stack<double>num;//存储整数
stack<char>op;//存储运算符
for(int i=0;i<len;i++)
{
if(s[i]==' ')//空格直接跳过
continue;
else if(s[i]=='*'||s[i]=='/')//乘除法,运算完后将结果进栈
{
double x=num.top();//拿出数字栈中的栈顶元素
num.pop();
double y=0;
int j;
for(j=i+2;j<len;j++)//提取出字符串中的整数
{
if(s[j]!=' ')
y=y*10+s[j]-'0';
else
break;
}
//将结果进栈
if(s[i]=='*')
num.push(x*y);
else
num.push(x/y);
i=j;
}
else if(s[i]=='+'||s[i]=='-')//加减法,直接进栈
op.push(s[i]);
else//数字则提取出来进栈
{
double y=0;
int j;
for(j=i;j<len;j++)
{
if(s[j]!=' ')
y=y*10+s[j]-'0';
else
break;
}
i=j;
num.push(y);
}
}
//因为进栈之后出栈顺序与运算顺序相反,所以要将栈内元素反转
stack<double>nnum;
stack<char>oop;
while(!num.empty())
{
double temp=num.top();
nnum.push(temp);
num.pop();
}
while(!op.empty())
{
char temp=op.top();
oop.push(temp);
op.pop();
}
while(!nnum.empty()&&!oop.empty())
{
double x=nnum.top();//拿出第一个整数
nnum.pop();
double y=nnum.top();//拿出第二个整数
nnum.pop();
char ope=oop.top();//拿出运算符
oop.pop();
//将结果进栈
if(ope=='+')
nnum.push(x+y);
else
nnum.push(x-y);
}
printf("%.2lf\n",nnum.top());
}
return 0;
}