问题描述
小F面临一个编程挑战:实现一个基本的计算器来计算简单的字符串表达式的值。该字符串表达式有效,并可能包含数字(0-9)、运算符+、-及括号()。注意,字符串中不包含空格。除法运算应只保留整数结果。请实现一个解析器计算这些表达式的值,且不使用任何内置的eval函数。
测试样例
样例1:
输入:
expression = "1+1"
输出:2
样例2:
输入:
expression = "3+4*5/(3+2)"
输出:7
样例3:
输入:
expression = "4+2*5-2/1"
输出:12
样例4:
输入:
expression = "(1+(4+5+2)-3)+(6+8)"
输出:23
样例5:
输入:
expression = "2*(5+5*2)/3+(6+8*3)"
输出:40
代码
#include <iostream>
#include <string>
#include <stack>
#include <cctype>
using namespace std;
int getPriority(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
long long compute(long long a, long long b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
return 0;
}
int solution(string expression) {
stack<long long> nums;
stack<char> ops;
for (int i = 0; i < expression.size(); i++) {
char c = expression[i];
if (isspace(c)) continue;
if (isdigit(c)) {
long long num = 0;
while (i < expression.size() && isdigit(expression[i])) {
num = num * 10 + (expression[i] - '0');
i++;
}
i--;
nums.push(num);
}
else if (c == '(') {
ops.push(c);
}
else if (c == ')') {
while (!ops.empty() && ops.top() != '(') {
long long b = nums.top(); nums.pop();
long long a = nums.top(); nums.pop();
char op = ops.top(); ops.pop();
nums.push(compute(a, b, op));
}
ops.pop(); // 弹出'('
}
else {
while (!ops.empty() && getPriority(ops.top()) >= getPriority(c)) {
long long b = nums.top(); nums.pop();
long long a = nums.top(); nums.pop();
char op = ops.top(); ops.pop();
nums.push(compute(a, b, op));
}
ops.push(c);
}
}
while (!ops.empty()) {
long long b = nums.top(); nums.pop();
long long a = nums.top(); nums.pop();
char op = ops.top(); ops.pop();
nums.push(compute(a, b, op));
}
return nums.top();
}
int main() {
cout << (solution("1+1") == 2) << endl;
cout << (solution("3+4*5/(3+2)") == 7) << endl;
cout << (solution("4+2*5-2/1") == 12) << endl;
cout << (solution("(1+(4+5+2)-3)+(6+8)") == 23) << endl;
cout << (solution("2*(5+5*2)/3+(6+8*3)") == 40) << endl;
return 0;
}
思路:
首先创建两个栈:一个栈存数字,一个栈存操作符
首先遍历字符串
若当前字符为数字,则处理当前数字,将数字压入存数字的栈
若当前字符为符号,则判断当前符号与上一个符号的优先级,
若优先级低于上一个符号,则拿出数字栈顶的两个数字,和操作栈顶的符号,进行操作,得出的数字继续压入栈顶,然后当前符号也压入栈顶。
若大于上一个符号的直接压入栈顶
最后处理剩余的数字栈和字符栈
数字栈一定会剩余最后一个数字,这最后一个数字就是答案