js实现输入数学公式和参数,计算结果

本文介绍了一个使用JavaScript实现的数学表达式解析与计算工具。该工具可以将输入的数学公式转换为后缀表达式,并计算其结果。具体包括公式转Token、中缀表达式转后缀表达式及计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

js实现输入数学公式和参数,计算结果

class CalFormula {
    constructor(formula, params) {
        this.formula = formula
        this.params = params
    }
    // 公式字符串转换成token数组(中缀表达式)
    formulaToToken() {
        // 匹配运算符和空格
        const REG = /[()+\-/\*\^ ]/g;
        const params = this.formula.split(REG).filter(Boolean)
        const tokens = []
        let tmpStr = this.formula.replace(/\s/g,'')
        while (tmpStr.length > 0) {
            if(tmpStr.startsWith(params[0])) {
                tmpStr = tmpStr.replace(params[0], '')
                tokens.push(params.shift())
            } else {
                tokens.push(tmpStr[0])
                tmpStr = tmpStr.substring(1)
            }
        }
        return tokens
    }
    // 中缀表达式转换成后缀表达式(逆波兰表达式)
    toPostfix() {
        const operatorRank = { 
            '(': 0, 
            ')': 0, 
            '+': 1, 
            '-': 1, 
            '*': 2, 
            '/': 2, 
            '^': 3 
        };
        const tokenList = this.formulaToToken()
        const result = []
        const operatorStack = []
        for (const token of tokenList) {
            // 如果是运算符
            if(this.isOperator(token)) {
                while (operatorStack.length > 0 && operatorRank[token] <= operatorRank[operatorStack[operatorStack.length - 1]]) {
                    const operator = operatorStack.pop()
                    result.push(operator)
                }
                operatorStack.push(token)
            } else if (token === '(') {
                operatorStack.push(token)
            } else if (token === ')') {
                while (operatorStack[operatorStack.length - 1] !== '(') {
                    const operator = operatorStack.pop()
                    result.push(operator)
                }
                operatorStack.pop()
            } else {
                result.push(token)
            }
        }
        while (operatorStack.length > 0) {
            result.push(operatorStack.pop())
        }
        return result
    }
    // 是否是运算符
    isOperator(str) {
        const operatorReg = /[+\-/\*\^]/;
        return operatorReg.test(str)
    }
    // 运算符到实际操作映射
    calculator(num1, num2, operator) {
        const calculators = {
            '+': (num1, num2) => (num1 + num2),
            '-': (num1, num2) => (num1 - num2),
            '*': (num1, num2) => (num1 * num2),
            '/': (num1, num2) => (num1 / num2),
            '^': (num1, num2) => (Math.pow(num1, num2))
        }
        return calculators[operator](num1, num2)
    }
    // 计算后缀表达式
    calPostfix() {
        console.log('rpn', this.toPostfix())
        const tokenList = this.toPostfix()
        const numarr = []
        for (const token of tokenList) {
            if (this.isOperator(token)) {
                const num2 = numarr.pop()
                const num1 = numarr.pop()
                const res = this.calculator(num1, num2, token)
                numarr.push(res)
            } else {
                numarr.push(this.params[token])
            }
        }
        console.log(numarr[0])
        return numarr[0]
    }

}


const formula = '((a + b -c) * d / f) ^ g'
let params = {
    a: 2,
    b: 2,
    c: 3,
    d: 5,
    f: 1,
    g: 2,
    h: 3,
}

new CalFormula(formula, params).calPostfix()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值