算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、/以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。
题目思路:前缀也好,后缀也罢,考察堆栈的基本应用。
#include<iostream>
#include<cctype>
#include<stack>
#include<string>
using namespace std;
int main()
{
stack<double> st; //定义一个栈,用于中缀计算
string s;
getline(cin, s); //string头文件里的函数,把表达式用字符串存起来
for (int i = s.size() - 1; i >= 0; i--)
{
if (isdigit(s[i])) //如果第i+1个元素是一个数
{
double mul = 10, num = s[i] - '0'; //把第i+1位置这个数值取出来
for (i--; i >= 0; i--) //判断第i个位置是什么
{
if (isdigit(s[i])) //如果是一个数
{
num += mul * (s[i] - '0'); //那么这个数就是十位数
mul *= 10; //更新mul,因为下第i-1位置上可能还是一个数,也就是百位
}
else if (s[i] == '.') //如果第i位置上是小数点
{
num /= mul; //方才第i+1位置上的数属于小数点的位置
mul = 1; //同样更新mul
}
else if (s[i] == '-') //如果第i位置上是负号
{
num = -num; //将该数设置为负数
}
else
break;
}
st.push(num); //将最终的算数压入栈中
}
else if (s[i] != ' ') //遇到运算符
{
double s1, s2, sum;
s1 = st.top(); //后入栈的元素(入栈时从右向左)
st.pop();
s2 = st.top(); //先入栈的元素
st.pop();
switch (s[i]) //进行运算
{
case'+':
sum = s1 + s2;
break;
case'-':
sum = s1 - s2;
break;
case '*':
sum = s1 * s2;
break;
case'/':
{
if (s2 == 0) //特别考虑除法的分布为0的情况
{
cout << "ERROR";
return 0;
}
sum = s1 / s2;
}
break;
}
st.push(sum); //运算好的结构在此压入栈
}
}
printf("%.1f", st.top());
}