栈的应用,看看计算机是如何实现加减乘除等四则运算的

从小学起大家就知道,先算乘除,再算加减,有括号先算括号里的内容。那么计算机是如何实现的呢?这是一个很深刻的问题。1929年波兰逻辑学家J.Lukasiewicz提出逆波兰(简称NPR)表达式,及后缀表达式,我们来看一个式子:
9 + (3 - 1)* 3 + 10 / 2;
这是我们常写的形式,我们称之为中缀表达式,那么后缀表达式该怎么写呢?如下:
9 3 1 - 3 * + 10 2 / +;
是不是很奇怪?觉得这小东西长得很别致,怎么会有人觉得这么写好呢?你不喜欢,我不喜欢,但计算机它一枝独秀啊,这么写对计算机来说很舒服,因为计算机的实现原理就是这样。这又涉及到栈的知识了。相比大家听说过栈的性质,就是迟到早退,先进后出,像给手枪弹夹装弹一样。
栈示意图
上面就是一个简单的栈(画的简陋,不要在意哈),元素只能往里面加,并且只有最上面的才能出去。那么这和后缀表达式有什么关系呢?又和计算机知道先算那个符号有什么关系呢?
首先我们来看计算机怎么会知道先算括号再乘除再加减的:
表达式:9 3 1 - 3 * + 10 2 / +;
原理:从左到右遍历后缀表达式,数字就入栈,符号就计算。具体实现如下:

  1. 初始化一个空栈,遇到9,不是符号,入栈,遇到3,不是符号,入栈,遇到1,不是符号,入栈,如图:
    入栈示意图
    2.然后遇到了减号,拿出来3和1进行减法运算并放入栈中,然后继续,发现3不是符号,入栈!

    3.然后遇到*,就将2和3拿出来相乘,结果6入栈,向后走遇到+号,拿出9和6相加入栈:

在这里插入图片描述
4.向后走,遇到10和2,入栈,遇到/号,将10和2拿出来相除,结果入栈:
在这里插入图片描述
5.最后遇到+号,拿出来相加,就得到结果20。

是不是觉得发明了后缀表达式的那个逻辑学家很厉害呢,反正我是被他的智慧折服了。那么这个后缀表达式是怎么来的呢?那肯定是由中缀表达式来的啊,怎么转的就又是一个问题了
规则如下:
从左到右遍历中缀表达式,数字则输出,成为后缀表达式的一部分,若是遇到符号,判断其余栈顶符号的优先级,是有括号或优先级不高于栈顶符号则栈顶元素依次出栈并输出
还是那个表达式:
9 + (3 - 1)* 3 + 10 / 2; ==》9 3 1 - 3 * + 10 2 / +;

  1. 初始化一个空栈,,第一个为9,输出,后面为“+”,进栈。左括号继续进栈:
    在这里插入图片描述
    2.然后是3,输出,“-”,入栈,1,输出(左图),直到遇到“)”,要与前面入栈的左括号相匹配,所以依次出栈并输出,由于左括号上面只有“-”,所以输出的结果如下(右图):

    3.紧接着是符号“*”,因为“*”优先级高于“+”,所以不输出,进栈,继续向后走,遇到3,输出
    (左图),接下来就关键了,遇到了“+”,其优先级比“*”优先级要小,因此全部出栈(右图),此时的那个“+”(9 + (3 - 1)* 3 +)最后那个“+”咱先放一边:
    在这里插入图片描述
    4.之前说过,栈里全部出来,然后把那个“+”先放着,现在咱么可以把“+”放进去了,现在栈里的“+”是该表达式最后一个“+”(见左图),此处比较乱,要好好看一下。继续向后走,遇到10,输出,遇到“/”,优先级高于“+”,入栈,遇到2,输出:
    在这里插入图片描述
    5.然后就没有然后了,到了结尾全部输出,所以最终结果为:9 3 1 - 3 * + 10 2 / +;
    多个括号也是一样,因为遍历中缀表达式后最先遇到的是里面的“)”,然后先处理最里面的括号。
    是不是看到这里就被这位逻辑学家的智慧所折服了呢?
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值