题目描述:
根据逆波兰表示法,求表达式的值。
有效的运算符包括 +
, -
, *
, /
。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
- 整数除法只保留整数部分。
- 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入: ["2", "1", "+", "3", "*"] 输出: 9 解释: ((2 + 1) * 3) = 9
示例 2:
输入: ["4", "13", "5", "/", "+"] 输出: 6 解释: (4 + (13 / 5)) = 6
示例 3:
输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] 输出: 22 解释: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = ((10 * (6 / (12 * -11))) + 17) + 5 = ((10 * (6 / -132)) + 17) + 5 = ((10 * 0) + 17) + 5 = (0 + 17) + 5 = 17 + 5 = 22
思路:
没啥好像的,这是栈的经典应用,数据结构课上都会讲。
这里还是提一下为什么要使用栈:因为碰到后面的特殊元素要对前面的元素进行处理,所以我们要使用栈。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int evalRPN(vector<string> &tokens) {
// 由逆波兰表达式确定该表达式的值
// 这里用一个vector<string>相当精妙
stack<string> tokens_stack;
set<string> sign_set = {"+", "-", "*", "/"};
for (string token : tokens) {
if (tokens_stack.empty()) { // 处理栈空的情况
tokens_stack.push(token);
} else if (sign_set.count(token)) { // 处理符号的情况
long long a = stoll(tokens_stack.top());
tokens_stack.pop();
long long b = stoll(tokens_stack.top());
tokens_stack.pop();
// 根据两个栈顶元素和符号确定结果
long long result;
if (token[0] == '+') result = a + b;
if (token[0] == '-') result = b - a;
if (token[0] == '*') result = a * b;
if (token[0] == '/') result = b / a;
// 压栈
tokens_stack.push(to_string(result));
} else { // 剩下的就是数字的情况
tokens_stack.push(token);
}
}
return stoi(tokens_stack.top());
}
int main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<string> tokens;
for (int i = 0; i < n; ++i) {
string str;
cin >> str;
tokens.push_back(str);
}
cout << evalRPN(tokens) << endl;
}
return 0;
}
其他经验:
- 突然发现很多时候我们存储参数的格式,已经被leetcode设计好了。比这道题就是vector<string>。这个做法其实很巧妙,首先他把数字和符号都按照字符串存储,数字字符串和数值本身的转换很容易(利用string头文件中的to_string和stoi等函数),本来只有一个字符的符号也被存储为字符串,所以我们要选取该字符串的第一个字符再进行判断。
- 第一点有点多了,这里再提一下,之所以vector中元素的类型会被设计为是string,是因为string是整型和字符型的上级;它所能表示的信息比这两个都要多,所以我们可以用string来表示整型和字符型混合的情况。
- 要取栈顶元素还是要考虑栈为空的情况啊!