简单四则运算解析器题解 | 豆包MarsCode AI 刷题
本题要求实现一个基本的计算器,用于计算包含加、减、乘、除以及括号的字符串表达式的值。这是一个典型的解析和计算问题,可以通过栈(Stack)数据结构来解决。栈用于存储操作数和操作符,以便按照正确的运算顺序进行计算。
解题步骤如下:
-
解析表达式:遍历字符串,识别数字和操作符,将数字转换为整数并存储,遇到操作符时,根据优先级进行处理。
-
处理操作符:对于加(+)和减(-),直接从栈中弹出两个操作数进行计算后将结果压入栈。对于乘(*)和除(/),由于它们具有更高的优先级,需要先计算它们。除法的结果需要向下取整。
-
处理括号:遇到左括号((),将当前计算的结果压入栈,并开始新的计算;遇到右括号()),将括号内的表达式计算完毕后,再与之前的计算结果进行合并。
-
计算结果:遍历结束后,栈中剩余的元素即为最终结果。
在实现过程中,我们需要注意以下几点:
- 操作符的优先级:乘除优先于加减,括号内的表达式优先于括号外的表达式。
- 操作符的结合性:加减和乘除都是左结合的,即从左到右计算。
- 除法的整数结果:除法运算应只保留整数结果,不进行四舍五入。
通过以上步骤,我们可以构建一个简单的计算器来解析和计算字符串表达式的值。这种方法不仅适用于本题,也可以扩展到更复杂的表达式解析和计算中。
在编写代码时,我们使用了两个栈,一个用于存储操作数,另一个用于存储操作符。通过遍历输入的表达式,我们依次处理数字和操作符,根据操作符的优先级和结合性来决定何时进行计算。最终,当遍历完整个表达式后,栈中剩余的元素即为计算结果。
这种方法的优点是逻辑清晰,易于实现,且能够正确处理包含括号的复杂表达式。缺点是对于非常长的表达式,可能会有较大的空间开销,因为需要存储整个表达式的操作数和操作符。但在大多数情况下,这种方法是解决此类问题的高效方式。
以下附上ACM模式下的cpp代码
#include <iostream>
#include <stack>
#include <string>
#include <cctype>
int precedence(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
int applyOp(int a, int b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b; // 注意:这里直接除以b,不进行四舍五入
}
return 0;
}
int calculate(std::string expression) {
std::stack<int> values;
std::stack<char> ops;
int i = 0;
while (i < expression.length()) {
if (expression[i] == ' ') {
++i;
continue;
}
if (expression[i] == '(') {
ops.push(expression[i]);
++i;
} else if (expression[i] == ')') {
while (!ops.empty() && ops.top() != '(') {
int val2 = values.top();
values.pop();
int val1 = values.top();
values.pop();
char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
if (!ops.empty()) ops.pop();
++i;
} else if (isdigit(expression[i])) {
int val = 0;
while (i < expression.length() && isdigit(expression[i])) {
val = (val * 10) + (expression[i] - '0');
++i;
}
values.push(val);
--i;
} else {
while (!ops.empty() && precedence(ops.top()) >= precedence(expression[i])) {
int val2 = values.top();
values.pop();
int val1 = values.top();
values.pop();
char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
ops.push(expression[i]);
++i;
}
}
while (!ops.empty()) {
int val2 = values.top();
values.pop();
int val1 = values.top();
values.pop();
char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
return values.top();
}
int main() {
std::string expression;
std::cout << "Enter an expression: ";
std::cin >> expression;
std::cout << "The result is: " << calculate(expression) << std::endl;
return 0;
}