我们人类习惯于书写“中缀式”,如 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!
这是一道简单的栈问题,将数字字符存在栈中,当遇到运算字符的时候进行出栈操作进行相应运算即可。
下面上代码:
#include <stdio.h>
#include <string.h>
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
char s[101];
int dz[101];
scanf("%s",&s);
int lenth=strlen(s);
int top=0;
int flag=1;
for(int i=0;i<lenth;i++)
{
switch(s[i])
{
case '+':
dz[top-2]=dz[top-2]+dz[top-1];
top--;
break;
case '-':
dz[top-2]=dz[top-2]-dz[top-1];
top--;
break;
case '*':
dz[top-2]=dz[top-2]*dz[top-1];
top--;
break;
case '/':
if(dz[top-1]==0) flag=0;
else
{
dz[top-2]=dz[top-2]/dz[top-1];
top--;
}
break;
default:
dz[top]=s[i]-48;
top++;
break;
}
if(flag==0) break;
}
if(flag==0) printf("Division By Zero!\n");
else if(flag==1&&top==1) printf("%d\n",dz[top-1]);
else printf("Expression Error!\n");
}
return 0;
}