美文网首页程序员
栈的经典实用

栈的经典实用

作者: _BK_徐静 | 来源:发表于2018-04-26 00:15 被阅读9次

    在JVM的运行时数据区包括:方法区、虚拟机栈、本地方法栈、堆、程序计数器。而虚拟机栈描述的是JAVA方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息。

    对于开头提到的信息相信每个对JVM有了解的人都明白,但是刚看到栈帧中的操作数栈,并不知道是做什么的?我不知道大家有没有这样的经历,知道有这么一个操作数栈,但是具体是做什么的,运行过程是什么样儿的,并不是很清楚

    下面我们看两个表达式

    波兰表达式法:标准四则运算表达式, 也称 中缀表达式
    就是我们从小学习的四则运算的表达式。
    例1:9+(3-1)*3+10/2 = ?

    逆波兰表达式法 - 后缀表达式
    上述例1,转为后缀表达式为:9 3 1 - 3 * + 10 2 / +

    我们在计算例1的中缀表达式时,我们可以计算出结果是20,但是这样的描述,计算机无法实别,而计算机通过栈结构+后缀表达式,可以压栈出栈,得出表达式的结果。

    操作数栈的执行过程

    数字入栈,操作符,从栈中弹出操作数,计算结果,结果入栈

    第一步: 将后缀表达式从头开始依次压入栈


    图片.png

    第二步:当遇到操作符“-”时,从栈中弹出两个操作数,第一个弹出的作为减数,第二个作为被减数,进行运算,计算出结果为2

    图片.png

    第三步:将计算出的结果入栈:

    图片.png

    第四步:将3压入栈中


    图片.png

    第五步:处理"*"
    从栈中弹出3 作为乘数 弹出2作为被乘数,并将结果6压入栈中,结果如下图

    图片.png

    第六步:处理"+"
    从栈中弹出6作为加数弹出9作为被加数,计算 9+6=15,将结果15入栈


    图片.png

    第七步:10入栈,2 入栈


    图片.png

    第八步:处理 "/"
    弹出操作数2作为除数,10作为被除数,10/2=5,将结果5入栈


    图片.png
    第九步:处理"+"
    弹出操作数5作为加数,操作数15作为被加数,15+5=20,20即为结果

    上述是整个操作数栈的执行过程。

    讲到这里,大家应该能明白JVM栈中的操作数栈的具体作用和执行过程了,但是有一个问题还没有解决,中缀表达式是怎么转换后后缀表达式?接下来我们看一下转换过程,其实在中缀转后缀的过程中,使用到的数据结构也是栈。

    转换规则

    - 1、数字输出
    - 2、运算符进栈
    - 3、括号匹配出栈
    - 4、如栈顶优先级高,则输出后一位数字,再出栈操作符

    转换过程

    为了方便读者观看,我们把要转换的中缀表达式,在这里再显示一次,中缀表达式:9+(3-1)3+10/2
    第1步:根据上面的规则,数字9、3、1、输出,操作符+(-依次进栈,可以得到,栈中的内容如下图:

    图片.png
    第2步:这里需要注意一下,因为规则中,扩号匹配出栈,怎么理解呢,就是把左号到当前栈顶的符号依次弹出栈,加到输出结果中,
    图片.png
    第3步:处理"
    ",这里要注意一个,这个符合规则 的第4条,“”优先级要比现栈顶符号优先级高,所以先输出后面的数字3,然后将*入栈,再依次将操作符出栈。 图片.png

    第4步: "+ "入栈,输出10


    图片.png

    第5步:这时候和第三步情况一下,"/"优先级高于栈顶操作符“+”,所以先输出“/”后面的数字“2”,将"/"入栈, 依次将栈中操作符出栈,并输出


    图片.png 最终结果就是我们所需要的后缀表达式: 图片.png

    使用java代码模拟jvm操作数栈的计算过程

    相关代码传送门:
    https://github.com/18921569386/datastructure/blob/master/datastructure-base/src/main/java/com/albk/datastructure/base/statck/ext/OperateStack.java

    相关文章

      网友评论

        本文标题:栈的经典实用

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