7-21 求前缀表达式的值(25 分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。
输入样例:
+ + 2 * 3 - 7 4 / 8 4
输出样例:
13.0
思路
由于是前缀表达式,所以必然是先有运算符,再有两个数字的,所以我们从后往前遍历,24-45行代码是读取一个数字的,每读完一个数字就压入栈中,当读到运算符时,就将栈顶的两个元素取出st.top()
并删除这两个元素st.pop()
,然后计算值并将值压入栈中以便下次计算st.push(sum)
,注意一个小问题,46行写成else if
,原因自己想想就知道了。
AC代码
/* 提交时间 状态 分数 题目 编译器 耗时 用户 2018/7/5 09:47:48 答案正确 25 7-21 C++ (g++) 3 ms 17204111 测试点 结果 耗时 内存 0 答案正确 3 ms 384KB 1 答案正确 3 ms 384KB 2 答案正确 3 ms 384KB 3 答案正确 2 ms 384KB */
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
stack <double> st;
int main()
{
string s;
getline(cin, s);
for (int i = s.size() - 1; i >= 0; i--)
{
if (isdigit(s[i]))
{
double mul = 10, num = s[i] - '0';
for (i--; i >= 0; i--)
{
if (isdigit(s[i]))
{
num += (s[i] - '0') * mul;
mul *= 10;
}
else if (s[i] == '.')
{
num /= mul;
mul = 1;
}
else if (s[i] == '-')
num = -num;
else
break;
}
st.push(num);
}
else if (s[i] != ' ') //else
{
double a, b, sum;
a = st.top();
st.pop();
b = st.top();
st.pop();
switch (s[i])
{
case '+':
sum = a + b;
break;
case '-':
sum = a - b;
break;
case '*':
sum = a * b;
break;
case '/':
{
if (b == 0)
{
cout << "ERROR";
return 0;
}
sum = a / b;
}
}
st.push(sum);
}
}
printf("%.1lf", st.top());
}