考虑 JavaScript 中的运算符优先级评估数学表达式

问题

我们需要编写一个 JavaScript 函数,它接受一个数学表达式作为一个字符串,并将其结果作为一个数字返回。

我们需要支持以下数学运算符 -

  • 除法 /(作为浮点除法)

  • 加法 +

  • 减法 -

  • 乘法 *

运算符总是从左到右计算,* 和 / 必须在 + 和 - 之前计算。

示例

以下是代码 -

const exp = '6 - 4';

const findResult = (exp = '') => {

   const digits = '0123456789.';

   const operators = ['+', '-', '*', '/', 'negate'];

   const legend = {

      '+': { pred: 2, func: (a, b) => { return a + b; }, assoc: "left" },

      '-'&: { pred: 2, func: (a, b) => { return a - b; }, assoc: "left" },

      '*': { pred: 3, func: (a, b) => { return a * b; }, assoc: "left" },

      '/': { pred: 3, func: (a, b) => {

      if (b != 0) { return a / b; } else { return 0; }

   }

   }, assoc: "left",

   'negate': { pred: 4, func: (a) => { return -1 * a; }, assoc: "right" }

};

exp = exp.replace(/\s/g, '');

let operations = [];

let outputQueue = [];

let ind = 0;

let str = '';

while (ind < exp.length) {

   let ch = exp[ind];

   if (operators.includes(ch)) {

      if (str !== '') {

         outputQueue.push(new Number(str));

         str = '';

      }

      if (ch === '-') {

         if (ind == 0) {

            ch = 'negate';

         } else {

            let nextCh = exp[ind+1];

            let prevCh = exp[ind-1];

            if ((digits.includes(nextCh) || nextCh === '(' || nextCh === '-') &&

               (operators.includes(prevCh) || exp[ind-1] === '(')) {

                  ch = 'negate';

            }

         }

      }

      if (operations.length > 0) {

         let topOper = operations[operations.length - 1];

         while (operations.length > 0 && legend[topOper] &&

         ((legend[ch].assoc === 'left' && legend[ch].pred <= legend[topOper].pred) ||

         (legend[ch].assoc === 'right' && legend[ch].pred < legend[topOper].pred))) {

            outputQueue.push(operations.pop());

            topOper = operations[operations.length - 1];

         }

      }

      operations.push(ch);

   } else if (digits.includes(ch)) {

      str += ch

   } else if (ch === '(') {

      operations.push(ch);

   } else if (ch === ')') {

      if (str !== '') {

         outputQueue.push(new Number(str));

         str = '';

      }

      while (operations.length > 0 && operations[operations.length - 1] !== '(') {

         outputQueue.push(operations.pop());

      }

      if (operations.length > 0) { operations.pop(); }

   }

   ind++;

}

if (str !== '') { outputQueue.push(new Number(str)); }

   outputQueue = outputQueue.concat(operations.reverse())

   let res = [];

   while (outputQueue.length > 0) {

      let ch = outputQueue.shift();

      if (operators.includes(ch)) {

         let num1, num2, subResult;

         if (ch === 'negate') {

            res.push(legend[ch].func(res.pop()));

         } else {

            let [num2, num1] = [res.pop(), res.pop()];

            res.push(legend[ch].func(num1, num2));

         }

      } else {

         res.push(ch);

      }

   }

   return res.pop().valueOf();

};

console.log(findResult(exp));

输出结果
2

以上是 考虑 JavaScript 中的运算符优先级评估数学表达式 的全部内容, 来源链接: utcz.com/z/331785.html

回到顶部