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

猜你喜欢

转载自blog.csdn.net/weixin_44439874/article/details/125484158
今日推荐