19年3月份的第二道题,刚开始用暴力法只能得30分,原因是无法正确处理除法,看了大佬们的博客之后,发现原来用栈解决运算问题这么简单,想明白之后来写一下笔记
用栈解决这道题的思路大体上就是利用两个栈:数据栈和符号栈,将数据入栈存储在数据栈中,将符号入栈存储到符号栈中,运算时将两个数据出栈,一个符号出栈,让出栈的数据与符号进行运算并将结果压入到数据栈中这样就可以不断累积进行计算了
#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
using namespace std;
int n;
int y;
stack<char> z;
stack<int> s;
char c[10];
bool can(char z) {
if (z == 'x' || z == '/') {
return 1;
}
else {
return 0;
}
}
void count(char z) {
int a = s.top();
s.pop();
int b = s.top();
s.pop();
switch (z)
{
case '+': y = a + b; break;
case 'x':y = a * b; break;
//细节!!后出栈的是前面的那一位,所以必须要放在被除数上
case '/':y = b / a; break;
}
s.push(y);
}
int main(void) {
cin >> n;
while (n--) {
while (!z.empty()) { z.pop(); }
while (!s.empty()) { s.pop(); }
cin >> c;
for (int i = 0; i < strlen(c); i++) {
if (c[i] >= '0' && c[i] <= '9') {
s.push(c[i] - '0');
}
else if (can(c[i])) {
s.push(c[++i] - '0');
count(c[i - 1]);
}
else if (c[i] == '-') {
z.push('+');
s.push((c[++i] - '0') * (-1));
}
else {
z.push(c[i]);
}
}
while (!z.empty()) {
count(z.top());
z.pop();
}
if (s.top() == 24) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
}
return 0;
}
整个过程比较简单,要注意几个细节:
1.正确的处理减法:因为减法在栈运算中是比较麻烦的,一个减法还可以进行运算,但出现多个减法就不行了,所以我们把减法转化成加原数的负数
2.处理除法的时候要注意,因为栈是先入后出,所以出栈的时候先出来的是除数,后出来的是被除数,在表达式的顺序上不要搞混
3.因为输入字符串的时候数据类型都是字节形式,但是我们要进行计算的话必须转换成整型,这里char类型转换成int类型使用的是char-'0’的方法