56 lines
2.4 KiB
JavaScript
56 lines
2.4 KiB
JavaScript
/**
|
||
* https://leetcode.cn/problems/basic-calculator/?envType=study-plan-v2&envId=top-interview-150
|
||
* @param {string} s
|
||
* @return {number}
|
||
*/
|
||
const calculate = function (s) {
|
||
|
||
};
|
||
|
||
/*
|
||
定义一个sign变量,表示数前面的符号,当数字收集完毕就使用这个符号操作,这个变量的默认值为+1,原因很简单,
|
||
表达式为一个整体,可以理解为一个括号,这个括号之前隐式的包含了一个+号,比如表达式 -1 + 2 -(1-2),可以
|
||
把它看成+(-1 + 2 -(1-2)),我们还需要使用一个栈结构来保存每一层括号表示的符号,以上面的表达式为例,第一个
|
||
括号显然为+,所以栈结构为[+1],之后这个括号下一级的数都会受它影响,比如括号里面的-1会变为1*-1,1*(+2)都
|
||
保持不变,当遇到"("时需要把这一层的符号压入栈中,栈结构为[+1,-1],第二级的括号里面的数都会受他影响,当遇到
|
||
)表示,这一层级的数都操作完必了,栈中无需保存这一层级的符号,直接弹出即可,这样一次遍历即可得到结果。
|
||
*/
|
||
|
||
function f1(s) {
|
||
const opt = [1];// 保存每一层括号的符号,初始表达式可以看成一个整体,所以默认值为[1]
|
||
let sign = 1; // 收集数字之后,数字前面的符号
|
||
let ret = 0; // 计数求和的结果
|
||
|
||
const n = s.length; // 字符串的长度,用于控制遍历
|
||
let i = 0; // 遍历下标
|
||
|
||
while (i < n) {
|
||
if (s[i] === ' ') { // 遇到空格直接跳过
|
||
i++;
|
||
} else if (s[i] === '+') { // 如果遇到加号,根据当前层级的符号更新sign
|
||
sign = opt[opt.length - 1];
|
||
i++;
|
||
} else if (s[i] === '-') { // 如果遇到减号,和上面同理
|
||
sign = -opt[opt.length - 1];
|
||
i++;
|
||
} else if (s[i] === '(') { // 遇到左括号,表明层级加深,把sign压入栈中即可
|
||
opt.push(sign);
|
||
i++;
|
||
} else if (s[i] === ')') { // 遇到右括号,表明当前层级处理完毕,把当前层级的符号弹出即可
|
||
opt.pop();
|
||
i++;
|
||
} else {
|
||
// 上面的情况处理完毕,在这里只有一种情况,那么就是数字本身,数字可能是多位数,所以
|
||
// 需要一次遍历来收集
|
||
let num = 0; // 用于收集数字
|
||
while (i < n && s[i] >= '0' && s[i] <= '9') {
|
||
num = num * 10 + (s[i] - '0');
|
||
i++;
|
||
}
|
||
// 数字收集完毕,通过它前面的符号sign和结果求和
|
||
ret += sign * num;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|