本文由我司收集整编,推荐下载,如有疑问,请与我司联系
Python
实现计算器
前几天有个面试题目:计算字符串
”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, ]
运算
符栈:
[
]
别忘了,我们第四次得到的运算符
’+’
号,此时,如果运算符栈中,弹出上
一次运算过的运算符
’+’
之后,还有别的运算符,
那么我们还应该将运算符栈的最
后一个运算符
和
本次得到的运算符
‘+’
进行比较,判断是否是同一级别。
如果
同一级别还得继续弹栈,继续运算。不在同一级别那就应该将运算符入栈。而现