js基于逆波兰表达式解析复杂四则运算

插件:js-big-decimal
import bigDecimal from ‘js-big-decimal’

// 四则运算
Vue.prototype.fourOperation = function(expression, floatNum) {
  function isOperator(value) {
    var operatorString = "+-*/()";
    return operatorString.indexOf(value) > -1
	}
  function getPrioraty(value) {
    switch (value) {
      case '+':
      case '-':
        return 1;
      case '*':
      case '/':
        return 2;
      default:
        return 0;
    }
  }
  function prioraty(o1, o2) {
    return getPrioraty(o1) <= getPrioraty(o2);
  }
  function dal2Rpn(exp) {
    let reg = RegExp(/\+|\-|\*|\/|\(|(|\)|)/g)
    let strSplit = exp.split(reg);
    let strMatch = exp.match(reg);
    let newStr = []
    let a = 0;
    for (var i = 0; i < strSplit.length; i++) {
      if (strSplit[i]) {
        newStr.push(strSplit[i]);
      }
      if (i != strSplit.length - 1) {
        newStr.push(strMatch[i]);
      }
    }
    let newStr1 = []
    for (var i = 0; i < newStr.length; i++) {
      if (i == 0 && newStr[i] == "-") {
        newStr1.push(newStr[i] + newStr[i + 1])
        i = i + 1;
      } else if (i - 1 >= 0 && newStr[i] == "-" && isNaN(newStr[i - 1])) {
        newStr1.push(newStr[i] + newStr[i + 1])
        i = i + 1;
      } else {
        newStr1.push(newStr[i])
      }
    }
    newStr = newStr1;
    var inputStack = [];
    var outputStack = [];
    var outputQueue = [];
    for (let i in newStr) {
      var cur = newStr[i];
      if (cur != ' ') {
        inputStack.push(cur);
      }
    }
    while (inputStack.length > 0) {
      var cur = inputStack.shift();
      if (isOperator(cur)) {
        if (cur == '(') {
          outputStack.push(cur);
        } else if (cur == ')') {
          var po = outputStack.pop();
          while (po != '(' && outputStack.length > 0) {
            outputQueue.push(po);
            po = outputStack.pop();
          }
          if (po != '(') {
            throw "error: unmatched ()";
          }
        } else {
          while (prioraty(cur, outputStack[outputStack.length - 1]) && outputStack.length > 0) {
            outputQueue.push(outputStack.pop());
          }
          outputStack.push(cur);
        }
      } else {
        outputQueue.push(cur);
      }
    }
    if (outputStack.length > 0) {
      if (outputStack[outputStack.length - 1] == ')' || outputStack[outputStack.length - 1] == '(') {
        throw "error: unmatched ()";
      }
      while (outputStack.length > 0) {
        outputQueue.push(outputStack.pop());
      }
    }
    return outputQueue;
  }

  function evalRPN(tokens) {
    let stack = [];
    for (let item of tokens) {
      switch (item) {
        case '+':
          let a1 = stack.pop();
          let b1 = stack.pop();
          stack.push(bigDecimal.add(b1, a1));
          break;
        case '-':
          let a2 = stack.pop();
          let b2 = stack.pop();
          stack.push(bigDecimal.subtract(b2, a2));
          break;
        case '*':
          let a3 = stack.pop();
          let b3 = stack.pop();
          stack.push(bigDecimal.multiply(b3, a3));
          break;
        case '/':
          let a4 = stack.pop();
          let b4 = stack.pop();
          stack.push(bigDecimal.divide(b4, a4, floatNum + 20));
          break;
        default:
          stack.push(parseFloat(item));
      }
    }
    return parseFloat(stack.pop());
  }
  
  let expArr = dal2Rpn(expression)
  let resultExp = evalRPN(expArr)
  return resultExp
}

使用
this.fourOperation(‘11+2233-44/50’,2)
console.log(this.fourOperation('11+22
33-44/50’,2)) // 输出:736.12

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值