问题描述
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
示例
输入:s = "3+2*2"
输出:7
解法
该问题可以使用栈来解决。具体步骤如下:
-
首先,初始化一个栈
stack和两个变量num和preOp。 -
然后,遍历字符串
s中的每个字符:-
如果当前字符是数字字符,则将其转换为整数,并累加到
num变量上。 -
如果当前字符是运算符或者字符串
s的末尾,则根据前面的preOp变量来决定如何将num入栈:- 如果
preOp是+,则将num直接入栈。 - 如果
preOp是-,则将-num入栈。 - 如果
preOp是*,则将栈顶元素乘以num,并将结果入栈。 - 如果
preOp是/,则将栈顶元素除以num,并将结果入栈(需要注意整数除法要向零取整)。
- 如果
-
如果当前字符是运算符,则将其赋值给
preOp变量,并将num重置为 0。
-
-
最后,遍历完整个字符串之后,将栈中所有元素累加起来,即为所求的结果。
代码实现
以下是使用 Typescript 实现的代码:
function calculate(s: string): number {
const stack = [];
let num = 0;
let preOp = "+";
for (let i = 0; i < s.length; i++) {
const c = s.charAt(i);
if (/\d/.test(c)) {
num = num * 10 + Number(c);
}
if (!/\d/.test(c) && c !== " " || i === s.length - 1) {
switch (preOp) {
case "+":
stack.push(num);
break;
case "-":
stack.push(-num);
break;
// 乘除要出栈
case "*":
stack.push(stack.pop() * num);
break;
default:
stack.push((stack.pop() / num) | 0);// 避免/0
break;
}
num = 0;
// 更新操作符
preOp = c;
}
}
// 余下的都是相加
return stack.reduce((a, b) => a + b, 0);
}
时间复杂度分析
由于需要遍历字符串 s 中的每个字符,因此时间复杂度为 ,其中 是字符串 s 的长度。在计算过程中,每个数字最多被入栈和出栈一次,因此空间复杂度为 。
因此,算法的时间复杂度为 ,空间复杂度也为 。