算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4
的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4
。请设计程序计算前缀表达式的结果值。
输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+
、-
、*
、/
以及运算数,不同对象(运算数、运算符号)之间以空格分隔。
输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR
。
看到前缀表达式我们应该很清楚这要从后往前看,即应先算出它的长度后再来个for函数从尾巴开始遍历。即
for(int i=n-1;i>=0;i--)
然后再进行判断有几个字符,如果超过了一个字符串里面有超过一个字符,那么它一定是数字。故:
(a[i].length()==1)
即使是一个字符串也不一定是数字,所以还要加
(a[i][0]=='+'||a[i][0]=='-'||a[i][0]=='*'||a[i][0]=='/')
这样子还不够,如果在有两个及两个以上数字时输入符号,那就是错误的,所以要加个
if(q.size()<2) {
error=1;
break;
}
然后就是朴实无华的用堆栈来解决这个问题了:
double top1=q.back(); q.pop_back();
double top2=q.back(); q.pop_back();
if(a[i][0]=='+') q.push_back(top1+top2);
else if(a[i][0]=='-') q.push_back(top1-top2);
else if(a[i][0]=='*') q.push_back(top1*top2);
else if(a[i][0]=='/') {
if(top2==0) {error=1;break;}
else q.push_back(top1/top2);
}
还有要记得如果是数字要把字符串转换成数字:
double t=atof(a[i].c_str());
最后就是一个简单的判断以及输出了:
if(q.size()!=1) error=1;
if(error==1) {cout<<"ERROR"; return 0;}
else printf("%.1f",q.back());
以下献上完整代码:
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
vector <double> q;//stack也行
int main(){
string a[100];
bool error=0;//用来判断是否出错的
int n=0;
while(cin>>a[n++]){}
n--;//上面的n多加了一个
for(int i=n-1;i>=0;i--){
if((a[i].length()==1)&&(a[i][0]=='+'||a[i][0]=='-'||a[i][0]=='*'||a[i][0]=='/')){
if(q.size()<2) {
error=1;
break;
}double top1=q.back(); q.pop_back();
double top2=q.back(); q.pop_back();
if(a[i][0]=='+') q.push_back(top1+top2);//计算过程
else if(a[i][0]=='-') q.push_back(top1-top2);
else if(a[i][0]=='*') q.push_back(top1*top2);
else if(a[i][0]=='/') {
if(top2==0) {error=1;break;}
else q.push_back(top1/top2);
}
}else {
double t=atof(a[i].c_str());
q.push_back(t);
}
}if(q.size()!=1) error=1;
if(error==1) {cout<<"ERROR"; return 0;}
else printf("%.1f",q.back());
return 0;//over~
}
return 0;