因为python list可以同时保存不同的数据, 并且提供丰富的操作方案, 想想可以同时把数字和运算符号都保存到列表中, 于是就诞生了使用列表写个表达式计算器, 思路就是同时将数字和运算符保存到列表, 然后从左向右计算所有乘除号两边的数值, 然后删除两个操作数和一个运算符, 再把运算结果保存到刚才计算的位置, 然后再第二次循环计算剩下的加减法运算, 最有元组只剩下一个数, 输出即结果,
检查符号是否为运算符号
nums = "0123456789"
optrs = "+-*/="
def isoperator(expression, index):
'''判断符号是运算符号还算是描述负数的符号'''
if nums.find(expression[index - 1]) != -1 and optrs.find(expression[index]) != -1:
return True
return False
将字符串表达式转换为列表
def gen_list(expression):
'''将输入的字符串表达式转换为列表'''
units = []#保存包含操作符和操作数的列表
start = 0#标记数字起点
expression = (expression if expression[len(expression) - 1] == "=" else expression + "=")
for i in range(len(expression)):
if (isoperator(expression, i)):
units.append(float(expression[start:i]))
units.append(expression[i])
start = i + 1
return units
计算只有简单加减乘除的表达式
def base_calculate(expression, isFirst = True):
'''计算只含有加减乘除的基本表达式'''
i = 0
while i < len(expression) - 3:
a = expression[i]#获取操作数1
b = expression[i + 2]#获取操作数2
optr = expression[i + 1]#或者运算符
tresult = None
if optr == "*":
tresult = a * b
elif optr == "/":
tresult = a / b
elif not isFirst and optr == "+":
tresult = a + b
elif not isFirst and optr == "-":
tresult = a - b
if tresult != None:
expression[i] = tresult#将第一个操作数替换问运算结果
del(expression[i + 1 : i + 3])#删除运算符号和后一个操作数
else:
i += 2#下标偏移
if isFirst:
return base_calculate(expression, False)
else:
return expression[0]#返回结果
通过以上的方案已经能计算任意不含括号的加减乘除运算, 但是我想要功能个更NB一点, 要能计算带括号的表达式, 怎么实现呢, 同先计算乘除法一样, 上面计算简单表达式的方法写成一个子函数, 然后再写一个递归函数递归计算带括号的表达式就OK了, 先计算最内部括号中的表达式, 然后将最内部的括号替换为计算后的结果, 在递归外部一层的, 最有留下的就是结果了
实现递归计算带括号的表达式
def calculate(expression):
'''递归计算带括号的表达式'''
if expression.find("(") == -1:#如果表达式不含符号, 直接返回计算结果
return base_calculate(gen_list(expression))
parathesis = []#做符号栈检查括号匹配
for i in range(len(expression)):
if expression[i] == '(':#遇到左括号, 表达式起点
parathesis.append(i)#保存左括号的下标
elif expression[i] == ')':#遇到右括号, 表达式终点, 遇到完整的一段表达式则递归计算
if len(parathesis) != 0:
subexp = expression[parathesis[-1] : i + 1][1 : -1]#截取子表达式
if subexp.find("(") == -1:#如果子表达式不含有括号了则计算
result = base_calculate(gen_list(subexp))#计算子表达式的结果
pre = expression[0 : parathesis[-1]]#括号前面的表达式
post = expression[i + 1 : ]#括号后面的表达式
expression = pre + str(result) + post#拼接为新的表达式
return calculate(expression)#递归计算
parathesis.pop()#删除一个左括号
执行入口
while True:
#输入表达式, 保证输入合法
expression = input('input a expression:')
print(calculate(expression))
将以上代码按顺序复制到python文件就能运行了