题解 | #四则运算#

四则运算

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)
})


全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务