题解 | #四则运算#
四则运算
https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
import sys
def cal(inp: str):
# 先算括号,把所有括号都清除,从大括号到小括号
for brace in ("{", "[", "("):
if brace in inp:
# 找到当前的第一对括号
start, end = find_brace(inp, brace)
# 递归计算括号内的结果,然后重新组装入参
inp = inp[:start] + str(cal(inp[start + 1 : end])) + inp[end + 1 :]
# 递归地得到结果
return cal(inp)
# 把去掉括号的字符串拆解成符号和数字,以列表形式存储,方便处理
stack = devide_inp(inp)
# 先计算乘除法,因为优先级更高
stack = cal_multi(stack)
# 最后计算加减法
res = cal_plus(stack)
return int(res)
def find_brace(inp, brace):
"""找到字符串inp的brace括号的第一个完整的括号序号"""
start, end = None, None
# 因为可能有重叠的括号,需要找到完整括号内的内容
brace_stack = []
brace_map = {"{": "}", "[": "]", "(": ")"}
for i, each in enumerate(inp):
if each == brace:
brace_stack.append(brace)
if start is None:
start = i
elif each == brace_map[brace]:
brace_stack.pop()
if not brace_stack:
end = i
break
return start, end
def devide_inp(inp: str):
"""把输入的字符串拆解成符号与数字"""
start, end = 0, 0
stack = []
for i, each in enumerate(inp):
if each not in ("+", "-", "*", "/"):
continue
end = i
# 拆分的时候注意负数的计算,如果两种符号连着的,就把负号也带上
if each == "-" and end - start == 0:
continue
stack.append(float(inp[start:end]))
stack.append(each)
start = i + 1
stack.append(float(inp[start:]))
return stack
def cal_multi(stack: list):
# 处理乘除的计算,直到再也找不到
# 从后往前处理,可以避免stack处理后,其后的序号出现变化的问题
for i in range(len(stack)-2, 0, -2):
if stack[i] not in ("*", "/"):
continue
if stack[i] == "*":
stack[i-1] *= stack[i+1]
stack.pop(i)
stack.pop(i)
else:
stack[i-1] *= stack[i+1]
stack.pop(i)
stack.pop(i)
return stack
def cal_plus(stack: list):
# 处理加减
while len(stack) > 1:
if stack[1] == "+":
stack[0] += stack[2]
stack.pop(1)
stack.pop(1)
elif stack[1] == "-":
stack[0] -= stack[2]
stack.pop(1)
stack.pop(1)
return stack[0]
for line in sys.stdin:
print(cal(line))
# 以下用Python的eval即可解决
# line = line.replace("[", "(")
# line = line.replace("]", ")")
# line = line.replace("{", "(")
# line = line.replace("}", ")")
# print(int(eval(line)))

