js 公式计算

  • Post author:
  • Post category:其他




参考:


js实现计算器(包含加减乘除括号)



功能:

传入包含未知数a,b,c的表达式,以及未知数值,计算结果



使用场景:

用户可通过编辑公式来操作数据,算出不同结果



代码如下:

const compute = (formulaABC, a, b, c) => {

    const formula = formulaABC.replace(/a/g, a).replace(/b/g, b).replace(/c/g, c).replace(/\s/g, '');

    // 如果是减法或除法,第一个是被减数/被除数
    const handleCalculation = (numArr, num1, num2, char) => {
        if (char == '+') {
            numArr.push(num1 + num2);
        } else if (char == '-') {
            numArr.push(num1 - num2);
        } else if (char == '*') {
            numArr.push(num1 * num2);
        } else if (char == '/') {
            numArr.push(num1 / num2);
        }
    }

    function isPop(char1, char2) {
        if ((char1 == '+' || char1 == '-') && (char2 == '+' || char2 == '-')) return true;
        if ((char1 == '+' || char1 == '-') && (char2 == '*' || char2 == '/')) return true;
        if ((char1 == '*' || char1 == '/') && (char2 == '*' || char2 == '/')) return true;
        if ((char1 == '*' || char1 == '/') && (char2 == '+' || char2 == '-')) return false;
    }

    // 分割字符串
    let arr = [];
    for (let i = 0; i < formula.length; i++) {
        let t = formula.charAt(i);
        let v = t;
        if (/[\d|\.]/.test(t + '')) {
            let j = i;
            for (; j < formula.length; j++) {
                let m = formula.charAt(j);
                if (!/[\d|\.]/.test(m + '')) {
                    break;
                }
            }
            v = formula.slice(i, j);
            if (j > i) {
                i = j - 1;
            }
            v = +v;
        }
        arr.push(v)
    }

    let charArr = [], numArr = [];
    for (let i = 0; i < arr.length; i++) {
        if (typeof arr[i] == 'number') {
            numArr.push(arr[i])
        } else {
            if (charArr.length) {
                // 关键步骤1
                // 这里如果当前的字符的优先级比栈顶的优先级低或相等,
                // 存储字符的栈要一直出栈直到栈为空或当前的字符的优先级比栈顶的优先级高,
                while (isPop(arr[i], charArr[charArr.length - 1])) {
                    let t2 = numArr.pop();
                    let t1 = numArr.pop();
                    let char = charArr.pop();
                    handleCalculation(numArr, t1, t2, char);
                }
                if (arr[i] == ')') {
                    let st = charArr[charArr.length - 1];
                    // 关键步骤2
                    // 遇到右括号也要一直出栈,直到遇到左括号,要注意边界问题
                    while (st != '(') {
                        let t1, t2;
                        let char = charArr.pop();
                        if (char != '(') {
                            t2 = numArr.pop();
                            t1 = numArr.pop();
                        }
                        handleCalculation(numArr, t1, t2, char);
                        st = char;
                    }
                }
                if (arr[i] != ')') {
                    charArr.push(arr[i])
                }
            } else {
                // 关键步骤3
                // 数字直接进栈
                charArr.push(arr[i])
            }
        }
    }
    // 关键步骤4
    // 最后字符栈如果还有字符,要一直出栈直到为空
    while (charArr.length) {
        let t2 = numArr.pop();
        let t1 = numArr.pop();
        let char = charArr.pop();
        handleCalculation(numArr, t1, t2, char);
    }
    return numArr[0];
}



版权声明:本文为TLROJE787原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。