问题描述:
实现一个基本计算器来计算简单的表达式字符串。
表达式字符串可能包含括号和以下运算符: +,-,*,/,和空格 。表达式字符串中的空格字符将被忽略。
您可以假设给定的表达式始终有效。
一些示例:
输入:s = "1 + 1" 输出:2
输入:s = " 6-4 / 2 " 输出:4
输入:s = "2*(5+5*2)/3+(6/2+8)" 输出:21
输入:s = "(2+6* 3+5- (3*14/7+2)*5)+3" 输出:-12
思路:
可以采用递归的方法来解决这个问题。对于当前要计算的表达式,我们需要将它分为两个部分:
- 计算没有括号的表达式。
- 计算有括号的表达式。
对于没有括号的表达式,我们可以直接从左到右计算。因为乘法和除法的优先级高于加法和减法,所以我们可以使用一个栈来存储数字和运算符。具体来说,我们从左到右扫描字符串,遇到数字时,我们将其压入栈中;遇到运算符时,我们将其与栈顶元素的运算结果压入栈中。
对于有括号的表达式,我们可以使用递归来计算。具体来说,我们先找到最里面的一层括号,然后计算括号内的表达式。我们重复这个过程,直到没有括号为止。
最后,我们需要注意一个细节。当我们遇到一个运算符时,如果栈顶元素为乘法或除法,那么我们需要先将它弹出,并计算运算结果,然后再将当前的运算符压入栈中。
下面是代码实现:
class Solution {
public int calculate(String s) {
int num = 0;
char sign = '+';
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
}
if (c == '(') {
int[] res = helper(s, i + 1);
num = res[0];
i = res[1];
}
if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1) {
if (sign == '+') {
stack.push(num);
} else if (sign == '-') {
stack.push(-num);
} else if (sign == '*') {
stack.push(stack.pop() * num);
} else {
stack.push(stack.pop() / num);
}
num = 0;
sign = c;
}
if (c == ')') {
break;
}
}
int res = 0;
while (!stack.isEmpty()) {
res += stack.pop();
}
return res;
}
private int[] helper(String s, int i) {
int num = 0;
char sign = '+';
Stack<Integer> stack = new Stack<>();
while (i < s.length()) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
}
if (c == '(') {
int[] res = helper(s, i + 1);
num = res[0];
i = res[1];
}
if ((!Character.isDigit(c) && c != ' ') || i == s.length() - 1) {
if (sign == '+') {
stack.push(num);
} else if (sign == '-') {
stack.push(-num);
} else if (sign == '*') {
stack.push(stack.pop() * num);
} else {
stack.push(stack.pop() / num);
}
num = 0;
sign = c;
}
if (c == ')') {
break;
}
i++;
}
int res = 0;
while (!stack.isEmpty()) {
res += stack.pop();
}
return new int[]{res, i};
}
}