理解题意:
我们人类习惯于书写“中缀式”,如 3 + 5 * 2
,其值为13
。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)
而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是: 3 5 2 * +
现在,请对输入的后缀式进行求值。为了简化输入处理和运算,运算数(操作数)不超过300
个且均为1位正整数,运算符(操作符)仅有+ - * /
(加减乘除)四种,运算数和运算符之间没有空格间隔,且题目保证运算的中间结果和最终结果都在整型范围内。
但是注意,题目输入的后缀式可能错误,例如:
1234+-
错误,缺少运算符123+-*
错误,缺少运算数122-/
错误,除数为0
题目保证以上三种错误不会同时发生。
输入格式:
第一行给出一个不超过10的正整数k;
接下来k行,每行给出一个后缀式,后缀式的格式如上文所描述,1位操作数且无空格间隔。
输出格式:
输出有k行,对于所输入的每个后缀式,判断是否正确(可求值),并在一行里输出:
- 如果后缀式无误、可求值,输出结果
- 如果发现除数为0,则输出
Division By Zero!
- 如果发现其它错误,则输出
Expression Error!
输入样例1:
2
1234+-*
123+4-*
输出样例1:
-5
1
输入样例2:
2
12+
1234+-
输出样例2:
3
Expression Error!
输入样例3:
2
2222+-*
22+-*
输出样例3:
-4
Expression Error!
输入样例4:
1
2222-/+
输出样例4:
Division By Zero!
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
代码如下:
#include <iostream>
using namespace std;
#define M 20
#define e -300
class stack{
private:
int* p;
int top;
int size;
bool isempty(){ return top==-1; }
public:
stack(){
p = new int[M];
top = -1;
size = M;
}
void push(int t) { p[++top]=t; }
int pop(){ return (isempty()==false)? p[top--] : e;}
bool isgo(){ return top>=1; } //判断栈中的元素个数是否>=2
~stack(){ delete[] p; p=nullptr; }
};
inline void test(char a[]){
stack pa; //创建栈对象
int j;
for(j=0;a[j]!='\0';j++){ //遍历字符数组,进行相应操作
if(isdigit(a[j])){
int t=a[j]-'0';
pa.push(t); //数字一律入栈
}else{
if(pa.isgo()){
int x=pa.pop(); //连取2个数,进行运算
int y=pa.pop();
int s; //计算结果
switch(a[j]){
case '+': s=y+x; break;
case '-': s=y-x; break;
case '*': s=y*x; break;
case '/': //swicth case,计算
if(x==0){
cout<<"Division By Zero!\n";
return;
}
s=y/x;
break;
default: cout<<"Expression Error!\n"; return;
}
pa.push(s); //计算结果入栈
}else{
cout<<"Expression Error!\n";
return;
}
}
}
if(pa.isgo()||j==1){ //如果栈中元素>=2,说明缺少运算符
cout<<"Expression Error!\n";
return;
}
cout<<pa.pop()<<endl; //如果计算成功,输出这一轮的结果
}
int main(){
int n;
cin>>n;
char a[n][M+1];
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) test(a[i]);
return 0;
}
------------------------ 希望有人可以指出我的错误!