题目一:
解法一:(栈)
解题思路:这个题就是遇到数字则压栈,遇到运算符,就出栈运算,需要注意的是,‘-’和‘/’这两个运算符,题目的意思是前一个数减去后一个数,而栈出栈的顺序相反,因此遇到‘-’的时候,后一个减去前一个,结果需要乘以-1,遇到‘/’的时候,也是需要前一个除以后一个,这个时候需要将当前元素和前一个元素记录下来,同时,JS中,如果是大于0的小数,是使用Math.floor(),而小于0的小数,使用的是Math.ceil()。最后需要注意的是,输入的是字符数组,遇到数字字符,压栈的时候是需要类型转换的。
var evalRPN = function(tokens) {
const stack = []
let cur = pre = null
for (let char of tokens) {
switch (char) {
case '+':
stack.push(stack.pop() + stack.pop())
break
case '-':
stack.push((stack.pop() - stack.pop()) * -1)
break
case '*':
stack.push(stack.pop() * stack.pop())
break
case '/':
cur = stack.pop()
pre = stack.pop()
stack.push(pre / cur > 0 ? Math.floor(pre / cur) : Math.ceil(pre / cur))
break
default:
stack.push(parseInt(char))
break
}
}
return stack.pop()
};
总结:for (let char of tokens) 其中char为单个字符,for (let char in tokens)其中char为索引,这也是for..of 和for...in的区别之一。
for in 和 for of 区别
首先,一句话概括:for in是遍历(object)键名,for of是遍历(array)键值。
1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of
2、for...in 循环出的是 key,for...of 循环出的是 value
3、注意,for...of 是 ES6 新引入的特性。修复了 ES5 引入的 for...in 的不足
4、for...of 不能循环普通的对象(如通过构造函数创造的),需要通过和 Object.keys()搭配使用
for in遍历数组的毛病:
1.index索引为字符串型数字,不能直接进行几何运算
2.遍历顺序有可能不是按照实际数组的内部顺序
3.使用for in会遍历数组所有的可枚举属性,包括原型。例如上述的原型方法method和name属性
所以for in更适合遍历对象,不要使用for in遍历数组。
那么除了使用for循环,如何更简单的正确的遍历数组达到我们的期望呢(即不遍历method和name),ES6中的for of更胜一筹。
解法二:(数组模拟)
var evalRPN = function(tokens) {
const n = tokens.length;
const stack = new Array(Math.floor((n + 1) / 2)).fill(0);
let index = -1;
for (let i = 0; i < n; i++) {
const token = tokens[i];
if (token === '+') {
index--;
stack[index] += stack[index + 1];
} else if (token === '-') {
index--;
stack[index] -= stack[index + 1];
} else if (token === '*') {
index--;
stack[index] *= stack[index + 1];
} else if (token === '/') {
index--;
stack[index] = stack[index] / stack[index + 1] > 0 ? Math.floor(stack[index] / stack[index + 1]) : Math.ceil(stack[index] / stack[index + 1]);
} else {
index++;
stack[index] = parseInt(token);
}
}
return stack[index];
};
解法三:
const SIGN = {
'*' : (a, b) => a * b,
'/' : (a, b) => Math.trunc(a / b),
'+' : (a, b) => a + b,
'-' : (a, b) => a - b
}
var evalRPN = function(tokens) {
const stack = [];
tokens.forEach(item => {
if (item in SIGN){
const b = stack.pop();
const a = stack.pop();
const res = SIGN[item](a, b);
stack.push(res);
}
else stack.push(Number(item));
})
return stack.pop();
};