201903-2二十四点

前言 这是一道表达式求值的题目,而且还是简单类型的,上学期老师也有给我们不知过这样的作业,要求比这题还要难一点。但是,在我做的时候,我却傻傻分不清四种运算符的优先级,总是搞乱了。所以,我觉得,我还是有必要写写这一道题的。
题目(带测试样例) 题目链接附上:二十四点
这里同样给出题目的截图:
【201903-2二十四点】
测试样例

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 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 a; stack 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; }

写在最后 这道题的表达式求值还是很简单的一种形式,推荐大家去把全部的符号都考虑进去,比如括号这些,博主因为时间有限,就不写了(明天就要考试了,五五)。以后有时间的话再来补充表达式求值的内容吧。好,那这道题就到这里,谢谢您的阅读哦。

    推荐阅读