前缀式计算
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
先说明一下什么是中缀式:
如2+(3+4)*5这种我们最常见的式子就是中缀式。
而把中缀式按运算顺序加上括号就是:(2+((3+4)*5))
然后把运算符写到括号前面就是+(2 *( +(3 4) 5) )
把括号去掉就是:+ 2 * + 3 4 5
最后这个式子就是该表达式的前缀表示。
给你一个前缀表达式,请你计算出该前缀式的值。
比如:
+ 2 * + 3 4 5的值就是 37
-
输入
-
有多组测试数据,每组测试数据占一行,任意两个操作符之间,任意两个操作数之间,操作数与操作符之间都有一个空格。输入的两个操作数可能是小数,数据保证输入的数都是正数,并且都小于10,操作数数目不超过500。
以EOF为输入结束的标志。
输出
- 对每组数据,输出该前缀表达式的值。输出结果保留两位小数。 样例输入
-
+ 2 * + 3 4 5 + 5.1 / 3 7
样例输出
-
37.00 5.53
解题思路
:要解决这个题,需要从前缀表达式的最后一位开始往前遍历,若是数据就进栈(当遇到小数时,需要进一步处理,具体方法看代码),当遇到字符时就弹出数据栈栈顶的两个数据,并与此运算符进行相应的运算并把计算结果作为新的数据进栈;直到遍历结束时,输出栈顶元素即可,输出后并把栈顶元素弹出,以免影响下次的结果。
具体代码:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stack>
using namespace std;
stack <double> dsta;
char s[1500];
int main()
{
while(gets(s))
{
int len=strlen(s);
for(int i=len-1;i>=0;i--)
{
if(s[i]==' ')
continue;
if(s[i]>='0'&&s[i]<='9')
{
int v=0;
if(s[i-1]!=' ')//此条件是对小数的处理
{
int j=0,a[10];
while(s[i]!=' ')
{
if(s[i]=='.')
{
i--;
continue;
}
a[j]=s[i]-'0';
j++;i--;
}
for(int k=j-1;k>=0;k--)
v=v*10+a[k];
dsta.push(v/pow(10,j-1));
}
else
dsta.push(s[i]-'0');
}
else
{
double a=dsta.top();dsta.pop();
double b=dsta.top();dsta.pop();
double c;
switch(s[i])
{
case '+':c=a+b;break;
case '-':c=a-b;break;
case '*':c=a*b;break;
case '/':c=a/b;break;
}
dsta.push(c);
}
}
printf("%.2lf\n",dsta.top());
dsta.pop();
}
return 0;
}