问题描述
实现一个基本的计算器来计算一个简单的字符串表达式的值。注意事项如下:
-
输入是一个字符串表达式(可以假设所给定的表达式都是有效的)
-
字符串表达式可以包含的运算符号为:左括号
(
, 右括号)
, 加号+
, 减号-
-
可以包含的数字为:非负整数(< 10)
-
字符串中不包含空格
-
处理除法 case 的时候,可以直接省略小数部分结果,只保留整数部分参与后续运算
-
请不要使用内置的库函数
eval
输入格式
如:3+4*5/(3+2)
数据约束
见题目描述
输出格式
计算之后的数字
输入样例:
1+1
3+4*5/(3+2)
4+2*5-2/1
(1+(4+5+2)-3)+(6+8)
输出样例:
2
7
12
23
算法分析
解析表达式:遍历字符串表达式,识别数字和运算符。
处理运算符优先级:使用两个栈,一个用于存储数字,另一个用于存储运算符。在遇到右括号或栈顶运算符优先级较高时进行计算。
计算表达式:根据运算符栈和数字栈进行计算,直至表达式解析完毕。
完整代码
#include <iostream>
#include <string>
#include<stack>
#include<unordered_map>
using namespace std;
// 辅助函数,计算两个数的运算结果
int calculate(int a, int b, char op) {
if (op == '+') return a + b;
if (op == '-') return a - b;
if (op == '*') return a * b;
if (op == '/') return a / b; // 只保留整数部分
return 0; // 其他运算符不考虑
}
// 主函数,计算表达式的值
int solution(string s) {
stack<int> numStack; // 数字栈
stack<char> opStack; // 运算符栈
unordered_map<char, int> precedence = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}}; // 运算符优先级
int i = 0;
while (i < s.size()) {
if (isdigit(s[i])) {
// 读取数字
numStack.push(s[i] - '0');
} else if (s[i] == '(') {
// 遇到左括号,直接入栈
opStack.push(s[i]);
} else if (s[i] == ')') {
// 遇到右括号,计算到左括号
while (!opStack.empty() && opStack.top() != '(') {
int b = numStack.top(); numStack.pop();
int a = numStack.top(); numStack.pop();
char op = opStack.top(); opStack.pop();
numStack.push(calculate(a, b, op));
}
opStack.pop(); // 弹出左括号
} else {
// 遇到运算符,进行计算直到栈顶运算符优先级低于当前运算符
while (!opStack.empty() && precedence[opStack.top()] >= precedence[s[i]]) {
int b = numStack.top(); numStack.pop();
int a = numStack.top(); numStack.pop();
char op = opStack.top(); opStack.pop();
numStack.push(calculate(a, b, op));
}
opStack.push(s[i]); // 当前运算符入栈
}
i++;
}
// 处理剩余的运算符
while (!opStack.empty()) {
int b = numStack.top(); numStack.pop();
int a = numStack.top(); numStack.pop();
char op = opStack.top(); opStack.pop();
numStack.push(calculate(a, b, op));
}
return numStack.top(); // 最终结果
}
int main() {
// You can add more test cases here
std::cout << (solution("1+1") == 2) << std::endl;
std::cout << (solution("3+4*5/(3+2)") == 7) << std::endl;
std::cout << (solution("4+2*5-2/1") == 12) << std::endl;
std::cout << (solution("(1+(4+5+2)-3)+(6+8)") == 23) << std::endl;
return 0;
}