python计算器总结_Python实现计算器

本文介绍了如何使用Python实现一个计算器,处理带有运算符优先级的复杂算式。通过压栈的方法,将字符串算式转化为列表,然后利用两个栈分别存储数字和运算符,遍历列表并根据运算符优先级进行计算。文章详细讲解了算法思路,包括如何处理算式列表、如何判断数字和运算符、如何决定入栈或出栈等关键步骤,并给出了核心函数的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天有个面试题目:计算字符串"1 + (5 - 2) * 3",结果为10,不能用eval()。今天介绍一下用压栈的方法解一解这个题目,事实上我们的计算器原理也是如此。

1 分析题目

(1)如果计算“1+2”这种两个数之间的运算,比较简单,可直接将“字符数字”1,2分解出来,强制转换为float类型,然后根据中间的运算符加减乘除就行。这题难在需要再复杂的算式中考虑运算符有优先级。

(2)通常我们在计算的时候,实际上也是不断进行两个数之间运算,并将算完的结果再和其他数进行运算。比如“1 + 2 + 4”,第一步先算出1+2=3之后,再用算出的结果3和4相加,得到最终结果7。

(3)如果我们能够将算式“1+2+4”,看做是一个处理好的列表:

将字符串算式 "1+2+4" 处理成: ['1', '+', '2', '+', '4']

那么我们可以通过压栈的方式计算出结果。首先设置两个列表(栈),分别存放 数字 和 运算符,然后遍历 ['1', '+', '2', '+', '4']:

遍历 处理过的算式列表:['1', '+', '2', '+', '4']

第一次:

得到数字'1', 转换成float, 放入数字栈:

数字栈: [1.0, ]

运算符栈: [ ]

第二次:

得到运算符'+',放入运算符栈:

数字栈:[1.0, ]

运算符栈:['+', ]

第三次:

得到数字'2',转换成float, 放入数字栈:

数字栈:[1.0, 2.0]

运算符栈:['+', ]

第四次:

得到运算符'+', 此时应注意:

运算符栈的最后一位也是'+'号, 现在又来了一个'+'号,说明相邻两个运算符的优先级别是一样的。

既然优先级别是一样的,四则运算法则告诉我们应该从左往右计算对吧?所以,此处不再一味地将运算符'+'入栈。而是:

(1)弹出数字栈中的最后两位数字,即 2.0 和 1.0 ;

(2)弹出运算符栈中的最后一个运算符'+';

(3)将弹出的数字和运算之间进行计算,即计算 2.0 + 1.0 = 3.0;

(4)将3.0放入数字栈,代替之前的 1.0 和 2.0;

即:

数字栈:[3.0, ]

运算符栈:[ ]

别忘了,我们第四次得到的运算符'+'号,此时,

如果运算符栈中,弹出上一次运算过的运算符'+'之后,还有别的运算符,

那么我们还应该将运算符栈的最后一个运算符 和 本次得到的运算符 '+' 进行比较,判断是否是同一级别。

如果同一级别还得继续弹栈,继续运算。不在同一级别那就应该将运算符入栈。

而现在,我们的运算符栈已经空了,那么应该把运算符'+'放入运算符栈,即:

数字栈:[3.0, ]

运算符栈:['+', ]

这样第四次才算大功告成。

第五次:

得到数字'4',转换成float, 放入数字栈:

数字栈:[3.0, 4.0]

运算符栈:['+', ]

至此我们已经遍历完算式列表:['1', '+', '2', '+', '4'],但在数字栈和运算符栈中还有元素。

那么我们应该依次弹出最后两个数字4.0 和3.0,以及最后一个运算符'+',然后进行运算,得到7.0,并代替原来数字栈中的4.0 和3.0,即:

数字栈:[7.0, ]

运算符栈:[ ]

最后得到的最终结果就是数字栈中的第一位元素:7.0。

通过描述计算 "1+2+4" 的过程,我们总结出这一方法计算的两个重点:

第一个重点:把算式处理成列表形式。如:'-1-2*((-2+3)+(-2/2))' 应该处理成:['-1', '-', '2', '*', '(', '(', '-2', '+', '3', ')', '+', '(', '-2', '/', '2', ')', ')'] 。

第二个重点:建立两个栈,数字栈和运算符栈。遍历算式列表,(从前往后取出列表中的元素),将数字放入数字栈,将运算符放入运算符栈。但是,需要通过运算符栈中的最后一个运算符 与 当前拿到的运算符 比较,判断出应该弹栈进行运算还是直接入栈。

2 总结算法

通过1中的分析我们大致可以整理出如下算法:

1 将算式整理成列表formula_list。

2 循环[为方便描述,我们把此处循环叫循环1],依次取出列表中的元素 e (element缩写)。

if e 是数字:

加入数字栈num_stack,获取下一个元素e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值