LeetCode 227 基本计算器(2) python实现

0. LeetCode 227 题解链接

这次和上一次(LeetCode 224 基本计算器)不同的是,这次计算器有乘除法,需要考虑不同的计算符号出现的情况。

1. 题目描述

  • 实现一个基本的计算器来计算一个简单的字符串表达式的值。

  • 字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

  • 示例 1:

输入: “3+2*2”
输出: 7

  • 示例 2:

输入: " 3/2 "
输出: 1

  • 示例 3:

输入: " 3+5 / 2 "
输出: 5

2. 思路

同样利用栈的思想。

  • 用四个变量辅助:stack, tmp, n, op

  • stack : 由于加减法的优先级没有乘除法高,当先出现加减法,再出现乘除法的时候,就用 stack 保存已经遍历过的加减法。

  • tmp:存储已经遍历到的表达式。视情况(op)决定是否将其追加到stack 末尾

  • n:存储当前遍历到的数字。

  • op:存储的是上一个计算符,如果有的话。

    • op 是乘除符号,而当前遍历到加减法:说明tmp 里的表达式已有乘除法,需要计算tmp = cal_tmp_cc(tmp)
    • op 是加减符号,而当前遍历到加减法:直接将当前遍历到的元素添加到tmp
    • op 是乘除符号,而当前遍历到乘除法:同样计算整合tmp 里表达式的计算结果
    • op 是加减符号,而当前遍历到乘除法:当前遍历的表达式优先级高于之前遍历到的,于是将tmp 里的内容追加到stack 里,待最后再做加减法;而tmp 则用于存储当前优先级更高的表达式。
    • 每次遍历到op,都需要将n 添加到tmp里,并且置零,好用于之后的累加。
    • 加减法和乘除法的计算单独写了两个函数。
def calculate(s):
	s = "".join(s.split())
	stack, tmp = [], []
	n, op = 0, ''
	for c in range(len(s)) :
		if s[c] in  ["*", "/"]:

			if op in ["*", "/"]:
				tmp.append(n)
				tmp = cal_tmp_cc(tmp)
			elif tmp:
				stack += tmp
				tmp = []
				tmp.append(n)
			else: 
				tmp.append(n)

			op = s[c]
			n = 0
			tmp.append(s[c])
		elif s[c] in ["+", "-"]:
			if op in ["*", "/"]:
				tmp.append(n)
				tmp = cal_tmp_cc(tmp)
			else:
				tmp.append(n)
			op = s[c]
			tmp.append(s[c])
			n = 0
		elif "0" <= s[c] <= "9":
			n = n * 10 + int(s[c])
		print(s[c], n, op, stack, tmp)
	tmp.append(n)
	if op in ["*", "/"]:
		tmp = cal_tmp_cc(tmp)
	stack += tmp
	print(stack, tmp)
	return cal_tmp_jj(stack)


def cal_tmp_cc(tmp):
	if tmp[1] == "*":
		return [int(tmp[0]) * int(tmp[2])]
	else:
		return [int(tmp[0]) / int(tmp[2])]


def cal_tmp_jj(tmp):
	res = 0
	n = 0
	op = 1
	for t in range(len(tmp)):
		if tmp[t] == "+":
			res += n * op
			op = 1
			n = 0 
		elif tmp[t] == "-":
			res += n * op
			op = -1
			n = 0
		elif tmp[t] != "(":
			n = n * 10 + int(tmp[t])
	res += n * op
	return str(res)



s = "3+2*2" 	# 7
# s = " 3+5 / 2 " 	# 5
# s = "14/3-2"	# 2
# s = "2*3*4"
res = calculate(s)
print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值