python用栈实现四则表达式(表达式中包含负数和小数)附全部代码

需求问题

在实际使用过程中,我们会遇到很多需要计算的地方,一般情况下我们使用系统的计算方法就实现:

a = -2.3+((1.0-1.0)/(89.0-1.0)*0.4+0.6)*-5 
print(a) 

输出:-5.3

或者使用eval方法:

a = "-2.3+((1.0-1.0)/(89.0-1.0)*0.4+0.6)*-5"
print(eval(a))

输出:-5.3

上述两种方法都可以算出公式的结果。但是存在一定的限制。例如,如果给出的算式中存在除数为0的情况呢?那上面两种办法就行不通了。
例: (2.0-1.0)/(89.0-89.0)*0.4+0.6,像这样的式子,计算的时候89.0-89.0结果为0,然而这个0又放在了除数的位置,所以就会发生错误。然我们的本身用意是式子中的除数为0的部分为计算结果指定为0,即式子中(2.0-1.0)/(89.0-89.0)该部分结果指定为0,后续的正常计算,那该式子的计算结果最终就等于0.6了。

要想要达到我们这样的目的,那上述的方法就行不通,于是我们就需要自己来实现四则运算。

解决方案

例:-2.3+((1.0-1.0)/(89.0-1.0)*0.4+0.6)*-5,因为我们的需求是式子中可能包含小数,或者负数,在我们人工计算的时候,我们会区分开哪个是整数,哪个是小数,哪个是负数,这样我们才能进行计算;所以我们在用程序计算这个式子的时候,我们也得需要区分开哪个是整数,哪个是小数,哪个是负数,即我们需要将式子转化为:

['-2.3', '+', '(', '(', '1.0', '-', '1.0', ')', '/', '(', '89.0', '-', '1.0', ')', '*', '0.4', '+', '0.6', ')', '*', '-5']

如果按照字符切分的话,那就会将上面的式子切成单个字符,如-2.3被切割成['-', '2', '.', '3'],这样肯定是不对的,切割成这样我们就无法计算了。

所以我们就先要对式子进行切分,切成我们用来计算的列表,就如同这样的式子:

['-2.3', '+', '(', '(', '1.0', '-', '1.0', ')', '/', '(', '89.0', '-', '1.0', ')', '*', '0.4', '+', '0.6', ')', '*', '-5']

然后我们才能进行后续的操作。

第一步:对算式进行切割,得到可以进行计算的列表;
第二步:将公式转化为后缀表达式(用栈实现);
第三步:从左到右依次访问后缀表达式,计算公式结果。

实现步骤

1、 对算式进行切割,得到可以进行计算的列表

def formula_charnge_to_list(formula):
	"""
	:param formula: 需要计算的公式,为全是值的公式,eg: ((1.0-1.0)/(89.0-1.0)*0.4+0.6)*5
	:return: 用于入栈计算的公式列表,负数或者小数被当做一个元素, eg:['(', '(', '1.0', '-', '1.0', ')', '/', '(', '89.0', '-', '1.0', ')', '*', '0.4', '+', '0.6', ')', '*', '5']
	"""
	a_list1 = list(formula.replace(" ", ""))    # 格式化公式,防止公式中的空格影响后续操作
	a_list2 = []    # 存储最终公式列表
	temp_str = ""
	for i in range(len(a_list1)):
		if a_list1[i] in "+*/()":
			if temp_str != "":
				a_list2.append(temp_str)
				temp_str = ""
			a_list2.append(a_list1[i])
		elif a_list1[i].isalnum() or a_list1[i] == ".":
			temp_str += a_list1[i]
		else:
			if i == 0:
				temp_str += a_list1[i]
			else:
				if a_list1[i-1].isalnum() and a_list1[i+1].isalnum():   # 3 - 3
					if temp_str != "":
						a_list2.append(temp_str)
						temp_str = ""
					a_list2.append(a_list1[i])
				elif a_list1[i-
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值