后缀表达式求值
时间限制: 1 Sec
内存限制: 128 MB
题目描述
为了便于处理表达式,常常将普通表达式(称为中缀表示)转换为后缀{运算符在后,如X/Y写为XY/表达式。在这样的表示中可以不用括号即可确定求值的顺序,如:(P+Q)(R-S) → PQ+RS-。后缀表达式的处理过程如下:扫描后缀表达式,凡遇操作数则将之压进堆栈,遇运算符则从堆栈中弹出两个操作数进行该运算,将运算结果压栈,然后继续扫描,直到后缀表达式被扫描完毕为止,此时栈底元素即为该后缀表达式的值。
输入
输入一行表示后缀表达式,数与数之间一定有空格隔开(可能不只一个空格),最后输入@表示输入结束。
数据保证每一步的计算结果均为不超过100000的整数。
输出
输出一个整数,表示该表达式的值.
样例输入
14 3 20 5 / * 8 - + @
样例输出
18
解题思路:
以字符的形式输入,存储在字符数组中(用 fgets 才能在字符数组中存储空格),遍历数组,遇到数字(注意字符与数字的转换)就入栈,遇到运算符就从栈中弹出两个数字进行运算,将运算结果入栈。直到运算到栈中只剩一个元素就是结果。
AC代码
#include<bits/stdc++.h> //万能头文件
using namespace std;
int is_num(char a); //判断是数字
int is_op_char(char a); //判断是运算符
int calculate(int i,int j,char c); //进行运算操作
int main(void)
{
stack<int>nums;
char c[300];
fgets(c,sizeof(c),stdin); //fgets能够读入空格,但gets不能读入空格。stdin表示从屏幕输入
int n = strlen(c); //下面循环最好不要i < strlen(c),因为每次strlen都要循环一边数组
int i,j;
for(i = 0; i < n ; ++i)
{
if(c[i] == '@')
break; //遇到@终止
if(is_num(c[i]))
{
int num = c[i]-'0';
for(j = i+1; is_num(c[j]) ; ++j) //当第i个是数字时,要往后找,直到不是数字的一个字符
{
num = num*10+(c[j]-'0'); //计算当前的数字
}
i = j; //找到数字之后要更新 i 的位置
nums.push(num); //将数字入栈
}
if(is_op_char(c[i])) //遇到运算符时,将栈顶的两个元素弹出进行运算
{
int a = nums.top();
nums.pop();
int b = nums.top();
nums.pop();
// cout<<b<<c[i]<<a<<'='<<op(b,a,c[i])<<endl;
nums.push( calculate( b, a,c[i] ) );
}
}
int ans = nums.top(); //判断栈中只剩一个元素(防止不正规输入)
nums.pop();
if(nums.empty())
cout << ans ;
return 0;
}
int is_num(char a)
{
if((a) >= '0' && (a) <= '9')
return 1;
return 0;
}
int is_op_char(char a)
{
if(((a) == '+') ||((a) == '-') ||((a) == '*') ||((a) == '/'))
return 1;
return 0;
}
int calculate(int a,int b,char op)
{
switch(op)
{
case'+':
return (a+b);
case'-':
return (a-b);
case'*':
return (a*b);
case'/':
return (a/b);
}
}