前缀表达式:从后往前扫,遇到操作数入栈、遇到字符时取两栈顶元素进行相应运算后结果入栈。
后缀表达式:与上类似,只是是从前往后扫。
求前缀表达式的值 (25 分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4
的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4
。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+
、-
、*
、/
以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR
。
输入样例:
+ + 2 * 3 - 7 4 / 8 4
输出样例:
13.0
AC代码:
#include<bits/stdc++.h>
using namespace std;
double op(double a,double b,char op){
if(op=='+') return a+b;
else if(op=='-') return a-b;
else if(op=='*') return a*b;
else if(op=='/') return a/b;
}
int main(){
//freopen("1.txt","r",stdin);
stack<double>S;
string prefixExp;
getline(cin,prefixExp);
for(int i=prefixExp.length()-1;i>=0;i--){
string digitExp="";
if(prefixExp[i]=='+'||prefixExp[i]=='-'||prefixExp[i]=='*'||prefixExp[i]=='/'){
double a=S.top();
S.pop();
double b=S.top();
S.pop();
if(b==0&&prefixExp[i]=='/'){
printf("ERROR");
return 0;
}
S.push(op(a,b,prefixExp[i]));
i--;
}
else{
do{
digitExp=prefixExp[i]+digitExp;
i--;
}while(i>=0&&prefixExp[i]!=' ');
S.push(stod(digitExp));
}
}
if(S.size()==1) printf("%.1f",S.top());
else printf("ERROR");
return 0;
}
后缀式求值 (25 分)
我们人类习惯于书写“中缀式”,如 3 + 5 * 2
,其值为13
。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)
而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是: 3 5 2 * +
现在,请对输入的后缀式进行求值。
输入格式:
在一行中输入一个后缀式,运算数
和运算符
之间用空格分隔,运算数长度不超过6
位,运算符仅有+ - * /
四种。
输出格式:
在一行中输出后缀式的值,保留一位小数。
输入样例:
3 5.4 2.2 * +
输出样例:
14.9
AC代码:
#include <iostream>
#include <stack>
#include <iomanip>
using namespace std;
int main(){
// freopen("1.txt","r",stdin);
stack<double>S;
string str;
while(cin>>str){
if(str=="+"||str=="-"||str=="*"||str=="/"){
double b=S.top();
S.pop();
double a=S.top();
S.pop();
if(str=="+") S.push(a+b);
else if(str=="-") S.push(a-b);
else if(str=="*") S.push(a*b);
else S.push(a/b);
}
else S.push(stod(str));
}
cout<<setprecision(1)<<std::fixed<<S.top();
return 0;
}