美文网首页
逆波兰表示(中缀表达式转后缀表达式计算)

逆波兰表示(中缀表达式转后缀表达式计算)

作者: zzglovecoding | 来源:发表于2020-09-06 23:35 被阅读0次

第一、意义

给你一个字符串,比如(9+(3-1))(3+(210/2)),如何计算他的值,必须是一般化的实现,不能说直接识别数字,然后怎样怎样。这里需要用到栈结构,就是中缀表达式转后缀,然后计算。
后缀表达式的计算规则,遇到数字就入栈,遇到操作符,就取出倒数第二个,作为第一个参数,倒数第一个,作为第二个参数,然后第一个操作第二个参数,这样来执行。
关键就是如何来计算出后缀表达式。

第二、实现中缀转后缀

规则:遇到数字,直接加入结果,遇到操作符,入栈,遇到优先级低于栈顶,或者右括号的情况,出栈,这部分书上讲得也有点不够细,网上很多人也基本瞎扯淡,我说一下。
stack是栈,final是最后的要输出的后缀表达式数组。
逻辑是这样的:
1、如果遇到( * /也就是左括号,乘除,直接入栈。
2、遇到),比如stack此时是( * ,这个时候)来了,就要把中间的所有操作符全部依次出栈加入final,()会抵消,也就是说,stack结束后变成了空
3、遇到 +或者-,就要比较栈顶操作符和他的优先级,比如此时栈顶是 * ,而此时是+操作符,那么这个时候,栈内东西依次全部出栈,除了(!注意,除了左括号!!左括号此时还是要留在里头的,遇到左括号就必须停下来。操作完了之后,这个+操作符会进入栈。

第三、代码实现

1、网上很多代码比较粗糙,没有考虑到直接split数组,把数字本身也拆开了的情况,比如''3+(2*10/2)",就这个,你一split,把10都拆成0和1了,所以我重写了一下字符串的split,弄成了strongSplit方法。
2、还有的,瞎扯淡,乱写逻辑,乱push值都不对。

//这个suffix方法就是转后缀表达式数组
function suffix(str) {
    let stack = [],
    final = [],
    strArr = strongSplit(str);

    for(let i = 0;i < strArr.length;i++) {
        if (')' === strArr[i]) {
            while(true) {
                var top = stack.pop();
                if ('(' !== top) {
                    final.push(top);
                }else {
                    break;
                }
            }
        }else if (['-','+'].indexOf(strArr[i]) > -1) {
            //如果新来的是这两个中的一个
            if (['*','/'].indexOf(stack[stack.length - 1]) > -1) {
                //优先级比不过栈顶
                while(stack.length > 0 && stack[stack.length - 1] !== '(') {
                    final.push(stack.pop());
                } 
            }
            stack.push(strArr[i]);
        }else if (['(','*','/'].indexOf(strArr[i]) > -1) {
            //如果是这几个,没有比他们大的,不需要向前看,直接加入栈
            stack.push(strArr[i]);
        }else {
            //就是数字
            final.push(strArr[i]);
        }
    }
    while(stack.length > 0) {
        final.push(stack.pop());
    }

    return final;
}

//拆解字符串的方法,防止数字本身也split,当然其他方法也可以,只要你够普通
function strongSplit(str) {
    var reg = /[\d]+/;
    var reg1 = /[+|\-|*|/|(|)]/;
    var arr = [];
    var tempStr = '';
    var s;
    for(let i = 0;i < str.length;i++) {
        if (s = reg1.exec(str[i])) {
            //说明就是个符号
            arr.push(s[0])
        }else if (reg.test(str[i]) && reg.test(str[i + 1])) {
            //说明后头一个还是数字
            tempStr += str[i];
        }else if (reg.test(str[i]) && !reg.test(str[i + 1])) {
            //说明下一个已经不是了
            tempStr += str[i];
            arr.push(tempStr);
            tempStr = '';
        }
    }
    return arr;
}



//计算后缀表达式最终值的算法
function computeSuffix(arr) {
    let reg = /[\d]+/,
    stack = [];
    for(let char of arr) {
        if (reg.test(char)) {
            //数字
            stack.push(char);
        }else {
            //符号
            var res,
            num1 = parseInt(stack.pop()),
            num2 = parseInt(stack.pop());
            if (char === '*') {
                res = num2 * num1;
            }else if (char === '/') {
                res = num2 / num1;
            }else if (char === '+') {
                res = num2 + num1;
            }else if (char === '-') {
                res = num2 - num1;
            }
            stack.push(res);
        }
    }
    return stack[0];
}

var s = '(9+(3-1))*(3+(2*10/2))'

console.log(computeSuffix(suffix(s)))

相关文章

  • [堆栈] 前, 中, 后缀表达式

    将中缀表达式转换成后缀表达式(逆波兰式), 便于计算机的计算.

  • 逆波兰计算器

    中缀表达式转换成后缀表达式 后缀表达式的计算 逆波兰计算器 先挖坑,学年设计之后再来填坑。

  • day06-逆波兰表达式的计算器

    目标:完成一个逆波兰表达式的计算器(分为两个步骤)计算后缀表达式:中缀表达式转成后缀表达式: 1.计算后缀表达式:...

  • 深度透析逆波兰表达式

    逆波兰表达式 1、概念 标准四则运算表达式---中缀表达式 计算机采用一种计算,变成后缀表达式: 2、计算机进行转...

  • 逆波兰式

    逆波兰式,是编程计算四则运算结果的算法。例子:平时写法a+b(中缀表达式),逆波兰式ab+。把中缀表达式编程后缀表...

  • C语言中缀表达式计算器

    本文将介绍中缀表达式计算器的详细写法,是 C语言把中缀表达式转换为后缀表达式 和 C语言逆波兰计算器 的结合 ...

  • 前缀,中缀,后缀表达式

    全文转载自:前缀、中缀、后缀表达式(逆波兰表达式),侵删。 前缀表达式,中缀表达式,后缀表达式都是四则运算的表达方...

  • 编译原理系列之九 中间代码生成

    中间代码生成 中间代码也与机器无关。 常见中间表示形式:逆波兰式:逆波兰式中缀表达式转逆波兰式:按照算术表达式的计...

  • 数据结构笔记-栈的应用-表达式转换问题

    关键字:表达式、中缀、前缀、后缀、波兰、逆波兰 概述 在数据结构中,栈有一个常见的应用就是计算机中表达式的计算。 ...

  • [数据结构]从中缀向后缀转换表达式 解题报告

    Problem Description 中缀表达式就是我们通常所书写的数学表达式,后缀表达式也称为逆波兰表达式,在...

网友评论

      本文标题:逆波兰表示(中缀表达式转后缀表达式计算)

      本文链接:https://www.haomeiwen.com/subject/edwhektx.html