BM49 表达式求值
知识点栈递归
描述
请写一个整数计算器,支持加减乘三种运算和括号。
数据范围:,保证计算结果始终在整型范围内
要求:空间复杂度: ,时间复杂度
示例1
输入:
"1+2"
复制返回值:
3
复制
示例2
输入:
"(2*(3-4))*5"
复制返回值:
-10
复制
示例3
输入:
"3+2*3*4-1"
复制返回值:
26
题解
栈的解法
使用2个栈nums和ops分别存放遍历时遇到的数字和非数字。按以下规则计算:
- 如果是'('直接入栈
- 如果是')'则取ops的栈顶元素和nums中的2个元素进行计算,直到ops的top为')'
- 如果是数字,则遍历直到非数字或者结尾的时候,将数字放入nums中
- 如果是+-*中的一个,则根据ops的栈顶元素判断优先级后计算
- 如果ops为空,或者栈顶元素为'(‘,则直接入栈
- 如果ops栈顶元素优先级不低于当前操作符优先级,则先计算后入栈
- 否则直接入栈
代码如下:
// 判断left和right操作符的优先级
// 如果可以优先计算left,则返回true,否则返回false
bool ops_priority(char left, char right)
{
if (left == '+' || left == '-')
{
return right != '*';
}
return true;
}
// 计算表达知
int calc(int left, int right, char op)
{
if (op == '+')
{
return left + right;
}
if (op == '-')
{
return left - right;
}
if (op == '*')
{
return left * right;
}
assert(false);
return 0;
}
class Solution
{
public:
int solve(string s)
{
std::stack<char> ops;
std::stack<int> nums;
int num = 0;
for (int i = 0; i < s.size(); ++i)
{
if (isalnum(s[i]))
{
num = num * 10 + (s[i] - '0');
if (i == s.size() - 1 || !isalnum(s[i + 1]))// 处理边界条件,将数字入栈
{
nums.push(num);
num = 0;
}
}
else if (s[i] == '(')
{
ops.push(s[i]);
}
else if (s[i] == ')')// 遇到有括号,则需要一直匹配到左括号,并将左括号出栈
{
while (ops.top() != '(')
{
int right = nums.top();
nums.pop();
int left = nums.top();
nums.pop();
nums.push(calc(left, right, ops.top()));
ops.pop();
}
ops.pop();
}
else // + - * 三中情况
{
if (ops.empty() || ops.top() == '(')
{
ops.push(s[i]);
}
else if (ops_priority(ops.top(), s[i]))
{
int right = nums.top();
nums.pop();
int left = nums.top();
nums.pop();
nums.push(calc(left, right, ops.top()));
ops.pop();
ops.push(s[i]);
}
else
{
ops.push(s[i]);
}
}
}
while (!ops.empty())
{
int right = nums.top();
nums.pop();
int left = nums.top();
nums.push(calc(left, right, ops.top()));
ops.pop();
}
return nums.top();
}
};