JavaScript实现逆波兰式

中缀表达式就是我们平时见到的算数表达式;前缀表达式被称为波兰式;后缀表达式被称为逆波兰式
在这里插入图片描述

中缀表达式转换逆波兰式实现逻辑

  • 创建运算符栈operator,结果栈result
  • 中缀表达式从左到右出栈
    • 当字符为数字时,直接压入result栈
    • 当字符为运算符时
      • 如果operator栈顶元素优先级不小于当前字符,则将operator栈顶元素出栈,直到operator栈顶元素优先级低于当前元素或遇到‘(’时将当前元素压入operation
    • 当前字符为“(”时,直接压入operator
    • 当前字符为")“时,将operator栈中的字符依次从栈顶压入result直到遇到第一个”("(停止并删除’(')或栈清空
  • 当中缀表达式清空时,将operator栈中的剩余字符依次压入result栈
        const calculator = (str) => {
            /**
             * operator:运算符栈
             * result:结果栈
             * nowIndex:当前下标
            */
            let operator = [], result = [], nowIndex = 0;
            const weight = {
                '+': 1,
                '-': 1,
                '*': 2,
                '/': 2,
                '(': 3,
                ')': 3,
            }
            while (str[nowIndex]) {
                if (str[nowIndex]) {
                    if (/\d/.test(+str[nowIndex])) {
                        // 数字
                        result.push(str[nowIndex])
                    } else if (/\(|\)/.test(str[nowIndex])) {
                        if (str[nowIndex] === '(') {
                            operator.push(str[nowIndex])
                        } else {
                            result.push(operator.pop())
                            while (operator[operator.length - 1] !== '(') {
                                result.push(operator.pop())
                            }
                            operator.pop()
                        }
                    } else if (/[\+\-\*\/]/.test(str[nowIndex])) {
                        // 符号
                        let nowTop = operator[operator.length - 1] //最顶层符号
                        while ((weight[str[nowIndex]] <= weight[nowTop]) && nowTop !== '(') {
                            result.push(operator.pop())
                            nowTop = operator[operator.length - 1]
                            // 也可以通过if判断里nowIndex-- 重新循环,但没有现在这么写节省性能
                        }
                        operator.push(str[nowIndex])
                    }
                }
                // 一定要写在最后,否正写在上面使用的时候会跳过下标为0的第一个值
                nowIndex++
            }
            while (operator.length) {
                result.push(operator.pop())
            }
            return result.join('')
        }

计算逆波兰式实现逻辑

  • 遍历逆波兰式,如果遇到数值则按顺序存储到数组中(push),如果遇到符号则用数组中最后两项进行计算并保存到数组中。
        const getResult = (str) => {
            let arr = str.split('');
            console.log(arr)
            let resultArr = []; //当前结果
            arr.forEach((item, index) => {
                if (/\d/.test(+item)) {
                    // 数字
                    resultArr.push(+item)
                } else {
                    // 字符
                    let firstFloor = resultArr.pop();
                    let secondFloor = resultArr.pop();
                    switch (item) {
                        case '+':
                            resultArr.push(secondFloor + firstFloor);
                            break;
                        case '-':
                            resultArr.push(secondFloor - firstFloor);
                            break;
                        case '*':
                            resultArr.push(secondFloor * firstFloor);
                            break;
                        case '/':
                            resultArr.push(secondFloor / firstFloor);
                            break;
                    }
                }
            })
            console.log(resultArr.pop())
        }

测试

        let jisuan = '1+(2-3)+3-4-(5-1)/2+3*2'
        let result = calculator(jisuan);
        getResult(result)   //3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值