前言
这是一道表达式求值的题目,而且还是简单类型的,上学期老师也有给我们不知过这样的作业,要求比这题还要难一点。但是,在我做的时候,我却傻傻分不清四种运算符的优先级,总是搞乱了。所以,我觉得,我还是有必要写写这一道题的。
题目(带测试样例)
题目链接附上:二十四点
这里同样给出题目的截图:
测试样例
10
9+3+4x3
5+4x5x5
7-9-9+8
5x6/5x4
3+5+7+9
1x1+9-9
1x9-5/9
8/5+6x9
6x7-3x6
6x4+4/5
思路
这个题目是用栈
来做的,我的做法是建立一个数字栈和一个符号栈。然后下面我来讲讲我的思路
首先,我们得到的是一个字符串,那么我们要怎样对它就行计算呢?那肯定就要进行转换呀!数字字符就转成我们的数字类型,符号字符就转成我们能操作的运算符类型,这个应该是不用讲的了。那么,我们来关心一下,我们要怎样进行运算呢?
我们回想一下,我们小时候学加减乘除时是不是有一个优先级?比如说先乘除再加减,同级运算从左到右进行·······
好,我们只有四种运算,这两条规则就够了。
我们先把字符串读进来,然后对它进行分析,是数字的话就压进数字栈
,是符号的话就压进符号栈
,不过,在压符号的时候,我们要注意些什么?没错,注意它的优先级。如果当前的字符的优先级比栈顶元素的低,那我是不是要先把前面的运算执行完了才能压入该符号?为什么?
举个例子,2*3+1,此时,我们判断+
该不该压进堆栈,显然不能,因为如果压进堆栈的话,那么我们进行运算的时候是不是会先算3+1?那这就不是我们的正确运算法则了。我们的法则是先乘除,后加减,同级运算从左到右进行
,也就是说,就算是同级,我们前面压进的字符也要比你后面压进的字符优先级要高,所以你后面的字符要压进来的话,你要先等我前面的运算完才可以进栈。
好,这样子,我们可以整出一个优先级的表,这个表应该还有更多的符号,我这里只是为了解这一道题,只给出以下四种,等我有时间了在补充写一写表达式求值
的内容,到时后再将他们补全吧。
a\b | + | - | * | / |
---|---|---|---|---|
+ | > | > | < | < |
- | > | > | < | < |
* | > | > | > | > |
/ | > | > | > | > |
表格中的a代表栈顶符号,b代表当前要压入的符号
这样,我们观察表格就会知道,只有到要压进的符号为*
或者/
的时候,它才能直接压进去,否则都要将里面有的符号先弹出计算才能压进去。这是一个很好的规律,帮助我们减少代码量。
好,既然已经分析到这里了,我想我们可以动手写代码了。代码里也有相应的注释,不懂的朋友可以看一看代码。
代码
/* 二十四点 */
#include <bits/stdc++.h>
using namespace std;
/* 运算操作 */
int operate(int a, char b, int c) {
if (b == '+') return a + c;
if (b == '-') return a - c;
if (b == 'x') return a * c;
if (b == '/') return a / c;
}
int n;
int main() {
cin >> n;
stack<int> a;
stack<char> b;
while (n--) {
string str;
cin >> str;
int len = str.length();
for (int i = 0; i < len; i++) {
if (isdigit(str[i])) { //如果是数字,压进数字栈
a.push(str[i] - '0');
} else {
if (b.empty()) //字符栈为空的话直接压栈
b.push(str[i]);
else if ((b.top() == '+' || b.top() == '-') && //如果是字符,判断优先级,如果是特殊的那种情况,直接压栈
(str[i] == 'x' || str[i] == '/')) {
b.push(str[i]);
} else { //否则先计算前面的
int num2 = a.top();
a.pop();
int num1 = a.top();
a.pop();
char c = b.top();
b.pop();
int num = operate(num1, c, num2);
a.push(num);
b.push(str[i]);
}
}
}
while (!b.empty()) { //将堆栈里面的符号全部拿出来计算
int num2 = a.top();
a.pop();
int num1 = a.top();
a.pop();
char c = b.top();
b.pop();
int num = operate(num1, c, num2);
a.push(num);
}
if (a.top() == 24)
cout << "Yes" << endl;
else
cout << "No" << endl;
a.pop();
}
return 0;
}
写在最后
这道题的表达式求值还是很简单的一种形式,推荐大家去把全部的符号都考虑进去,比如括号这些,博主因为时间有限,就不写了(明天就要考试了,五五)。以后有时间的话再来补充表达式求值
的内容吧。好,那这道题就到这里,谢谢您的阅读哦。