题解 | #四则运算#
四则运算
https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
// 根据栈顶运算符,与栈顶两个元素进行运算
function compute(st1,st2){
let b = st1.pop()
let a = st1.pop()
let op = st2.pop() // 栈顶运算符
if(op === '+'){
a = a + b
}else if(op === '-'){
a = a - b
}else if(op === '*'){
a = a * b
}else if(op === '/'){
a = a / b
}
st1.push(a)
}
// 比较运算符优先级
function priority(m,n){
// 如果当前栈顶为 * 或 / ,优先执行该运算符
if(!m){
return false
} else if(m === '('){
return false
}else if(m === '+' || m === '-' && n === '*' || n === '/'){
return false
}
return true
}
function test(s){
let stack1 = [] // 记录运算数字
let stack2 = [] // 记录运算符
let flag = false // flag用于标记每轮是否出现过数字, 数字之前的+-为正负号,数字之后的为加减号
for(let i=0;i<s.length;i++){
// 碰到 ( [ { 左括号,就将右括号 ) 压入栈中
if(s[i] === '(' || s[i] === '[' || s[i] === '{'){
stack2.push('(')
}else if(s[i] === ')' || s[i] === ']' || s[i] === '}'){ // 遇到右括号
while(stack2[stack2.length-1] !== '('){ // 弹出开始计算直到遇到左括号
compute(stack1,stack2)
}
stack2.pop() // 弹出左括号
}else if(flag){ // 运算符
while(priority(stack2[stack2.length-1],s[i])){ // 比较运算符优先级
compute(stack1,stack2) // 可以直接计算
}
stack2.push(s[i])
flag = false
}else{ // 数字
let j = i
if(s[i] === '+' || s[i] === '-'){ // 正负号
i++
}
// 如果截取部分为负数或者正数,直接推入栈中,如果符号为 * 或 / ,则i--,将flag标记掷为true,方便下次进入运算符判断中
while(/\d/.test(s[i])){
i++
}
let temp = s.substr(j,i-j)
stack1.push(Number(temp))
i--
flag = true // 数字结束,下一次flag为true就是运算符了
}
}
while(stack1.length > 1){
compute(stack1,stack2)
}
console.log(stack1.pop())
}
rl.on('line',function(line){
test(line)
})
