输入反而是最麻烦的)
思路
跟那道P1981表达式求值挺像的,这题就是把在里面的加减乘除放到了要算的数字后面,就拿例子来说:
3.5.2.-*7.+@
在这部分 3.5.2.-* 中我们可以看到3*(5–2)这个部分肯定是先算 - 号的,也就是说我们的运算顺序是按照在数字背后的运算符的顺序进行运算,先算的是 (5–2),也就是前面数字的最后两个进行减法运算,这就符合栈的规则,先进后出,值得注意的一点是要看清减数和被减数,是第二个出栈的减去第一个出栈的,除号也是如此,加号和乘号的话由于没有区别所以可以不用在意。
我们来模拟一次这个样例,新建一个栈s:
1. 将数字都入栈 3 5 2,直到碰到第一个运算符‘-’
2. 出栈两个数字, 5 2, 然后进行减法运算 5 - 2 = 3,然后把运算结果压回栈内,此时栈内的元素 3 3。
3. 继续读入,碰到第二个运算符‘*’,我们又出栈两个数字, 3 3, 然后进行乘法运算 3 * 3 = 9 ,将 9 压入栈内,此时栈内元素 9 。
4. 继续读入,遇到数字 7 ,将其压入栈内,直到遇到运算符‘+’,我们继续出栈两个数字 9 7 , 进行加法运算, 9 + 7 = 16 ,将其压入栈内,此时栈内元素 16 。
5. 读到字符‘@’,根据题意,结束读入,此时的栈顶元素 16 就是我们要的值!
我们来看下读入的部分
读入有很多种方法,比如
getchar()
就可以实现一个个字符读入
但是吧,老感觉很容易翻车,while循环加getchar一不小心就不知道读到那里去了。所以我个人推荐这种读一行字符的就还是用string方法直接cin来读入了。
string c;
cin >> c;
for(int i = 0; i < c.length(); i++)
{
}
以下是全部代码:
#include<iostream>
#include<stack>
using namespace std;
int n, m;
int main()
{
stack<int> s;
string c; cin >> c;
int cnt = 0;
for(int i = 0; i < c.length(); i++)
{
if(c[i] == '@') break;
if(c[i] == '.')
{
s.push(cnt);
cnt = 0;
}
else if(c[i] == '*')
{
int x = s.top();
s.pop();
int y = s.top();
s.pop();
cnt = x * y;
s.push(cnt);
cnt = 0;
}
else if(c[i] == '-')
{
int x = s.top();
s.pop();
int y = s.top();
s.pop();
cnt = y - x;
s.push(cnt);
cnt = 0;
}
else if(c[i] == '+')
{
int x = s.top();
s.pop();
int y = s.top();
s.pop();
cnt = x + y;
s.push(cnt);
cnt = 0;
}
else if(c[i] == '/')
{
int x = s.top();
s.pop();
int y = s.top();
s.pop();
cnt = y / x;
s.push(cnt);
cnt = 0;
}
else
{
cnt *= 10;
cnt += (c[i] - '0');
}
}
cout << s.top() << endl;
}