224. Basic Calculator
Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .
You may assume that the given expression is always valid.
Some examples:
"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23
这个问题主要就是括号怎么处理
递归
把对应的括号中的字符串递归的传到下一层函数中,得到括号中的结果。这样的做法会重复遍历很多遍字符串,比较慢,空间复杂度由于递归的原因也不会太好:
/**
* @param {string} s
* @return {number}
*/
var calculate = function(s) {
var l = s.length;
if (l === 0)
return 0;
if (l === 1)
return parseInt(s[0]);
var res = 0;
var op = 1;
var pass = '';
var needPass = 0;
var number = 0;
for(let i = 0;i < l;i++) {
if (s[i]===' ')
continue;
if (needPass===0&&pass.length===0) {
if (s[i]==='(')
needPass++;
else if (s[i] === '+') {
if (op===1) res += number;
else res -= number;
number = 0;
op = 1;
}
else if (s[i] === '-') {
if (op===1) res += number;
else res -= number;
number = 0;
op = 0;
}
else {
number = number*10 + parseInt(s[i]);
}
} else {
if (s[i]==='(') {
needPass++;
pass += s[i];
} else if (s[i]===')') {
needPass--;
if (needPass!==0) {
pass += s[i];
} else {
if (op===1) res += calculate(pass);
else res -= calculate(pass);
pass = '';
}
} else {
pass += s[i];
}
}
}
if (number!==0) {
if (op===1) res += number;
else res -= number;
}
return res;
};
栈
利用栈,每次遇到括号就把之前的值和该做的操作压入栈中保存起来,计算完括号中的值再取出来与括号中的值做运算,如果括号嵌套就一层一层的压进去。这样做的好处是只需要走一遍,事件复杂度是O(n)。
/**
* @param {string} s
* @return {number}
*/
var calculate = function(s) {
var stack = [];
var l = s.length;
if (l === 0)
return 0;
if (l === 1)
return parseInt(s[0]);
var res = 0;
var op = '+';
var number = 0;
for(let i = 0;i < l;i++) {
if (s[i] === ' ')
continue;
else if (s[i] === '(') {
stack.push(res);
stack.push(op);
res = 0;
op = '+';
}
else if (s[i] === ')') {
if (number !== 0) {
if (op === '+') res += number;
else res -= number;
number = 0;
}
let lastOp = stack.pop();
let lastRes = stack.pop();
if (lastOp==='+')
res = lastRes + res;
else
res = lastRes - res;
}
else if (s[i] === '+') {
if (op === '+') res += number;
else res -= number;
number = 0;
op = '+';
}
else if (s[i] === '-') {
if (op === '+') res += number;
else res -= number;
number = 0;
op = '-';
}
else {
number = number*10 + parseInt(s[i]);
}
}
if (number !== 0) {
if (op === '+') res += number;
else res -= number;
number = 0;
}
return res;
};
227. Basic Calculator II
Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.
You may assume that the given expression is always valid.
Some examples:
"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5
这个题相对上面的来说,木有括号,但是要先算乘和除。我们还是用栈来完成操作,这个解决方案108ms,打败100%哦~~
var calculate = function(s) {
var res = 0;
let l = s.length;
if (l === 0)
return res;
//记录上一个操作符
var op = '+';
//记录完整的数字
var num = 0;
//遍历指针
var index = 0;
//结果栈,这个栈里保存的将是每一个+和-之间的结果,-后面的结果会被取相反数存进栈
//最后把结果栈里的所有数相加就好
var stack = [];
while (index<l) {
//看看现在的是不是数字
let now = s.charCodeAt(index)-48;
//是的话就更新数字
if (now>=0&&now<10)
num = num*10+now;
//不是的话首先排除空格
//还有如果已经是最后一个字符了不管这个字符是什么都得进来完成最后一个数的计算,应该只可能是数字或空格
//剩下的就是在遇见符号的时候意味着上一个数字已经读完了,用上一个数字的操作计算上一个数字
if ((now<0||now>=10)&&now+16!==0||index === l - 1){
//如果上一个操作是+,直接放进栈
if (op==='+')
stack.push(num);
//如果上一个操作是-,就把相反数放进栈
else if (op==='-')
stack.push(-num);
//如果上一个操作是*,那就把前面一个结果也取出来,乘完作为一个结果放进去
else if (op==='*')
stack.push(stack.pop()*num);
//除同理
else
stack.push(parseInt(stack.pop()/num));
//更新操作符
op = s[index];
//更新数字
num = 0;
}
index++;
}
return stack.reduce((last,now) => last + now,0);
};