需求分析
day 5作业:模拟计算器开发
作者:keven
作业需求:
实现加减乘除及拓号优先级解析
用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,
必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),
运算后得出结果,结果必须与真实的计算器所得出的结果一致
流程:
1.解析字符串,区别 减号,与 复数。
2.利用栈方式,新建数字栈,符号栈。
3.调用,简单加,减,乘,除函数,调用符号优先级判断函数。
a、当栈顶符号的优先级大于、等于,入栈符号的优先级时,数字栈谈出末尾两个数字进行计算。
b、当栈顶符号的优先级 小于,入栈符号的优先级时,不做计算。
c、当遇到右括号时,依次弹出数字栈的数字,及符号栈的符号,进行计算。知道遇到左括号。
4.返回结果
import re
s="1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )"
#处理字符串, 主要是区别 减号,和 负数
def init_action(s):
#print(s)
s=re.sub(" ","",s)
print(s)
init_l=[i for i in re.split("(\-\d+\.*\d*)",s) if i]
print(init_l)
expression_l=[]
while True:
if len(init_l) == 0: break
exp=init_l.pop(0)
if len(expression_l) == 0 and re.search("^\-\d+\.*\d*$",exp):
expression_l.append(exp)
continue
# if len(expression_l) > 0:
# if re.search("[\+\-\*\/\(\)]]",expression_l[-1]):
# expression_l.append(exp)
# continue
if len(expression_l) > 0:
if re.search("^[\-][\d+]",exp) and not re.search("\d+",expression_l[-1]):
expression_l.append(exp)
continue
newl=[i for i in re.split("([\+\-\*\/(\)])",exp) if i]
expression_l+=newl
return expression_l
#程序主体
def main(expression_l):
#print("main",expression_l)
number_stack=[] #定义数字栈
symbol_stack=[] #定义符号栈
for ele in expression_l: #循环 出来后的字段
# print("*"*30)
# print("number_stack",number_stack)
# print("symbol_stack",symbol_stack)
# print("没有入栈",ele)
ret=is_symbol(ele) #判断字符是否是 运算字符,
if not ret: #如果不是运算符,压入数字栈
#print(ele)
ele=float(ele)
number_stack.append(ele)
else:
while True: #如果是运算字符
if len(symbol_stack) == 0: #当运算符栈为空,无条件压入栈
symbol_stack.append(ele)
break
res= priority(symbol_stack[-1],ele) #调用判断运算符 优先级函数,
if res == "<": #当后来入站优先级大于 运算符栈顶的运算符时,压入站内
symbol_stack.append(ele)
break
elif res == "=": # 优先级相等时,弹出栈顶运算符,准备计算
symbol_stack.pop()
break
elif res == ">": # 当优先级小于,运算符栈顶时 开始计算
symbol=symbol_stack.pop()
num2=number_stack.pop()
num1=number_stack.pop()
number_stack.append(calculate(num1,symbol,num2))
#print(number_stack,symbol_stack)
else:
while len(symbol_stack) > 0: #执行完成循环后,判断运算符内是否还有运算符,如果有继续计算
symbol = symbol_stack.pop()
num2 = number_stack.pop()
num1 = number_stack.pop()
number_stack.append(calculate(num1, symbol, num2))
#print(number_stack,symbol_stack)
return number_stack,symbol_stack
def priority(top_sym,wait_sym): #定义判断字符优先级函数,
#print(top_sym,wait_sym)
level1=["+","-"]
level2=["*","/"]
level3=["("]
level4=[")"]
if top_sym in level1:
if wait_sym in level2 or wait_sym in level3:
return "<"
else:
return ">"
elif top_sym in level2:
# if wait_sym in level1:
# return ">"
# elif wait_sym in level2:
# return ">"
# elif wait_sym in level3:
# return "<"
# elif wait_sym in level4:
# return ">"
# else:
# return ">"
if wait_sym in level3:
return "<"
else:
return ">"
elif top_sym in level3:
if wait_sym in level4:
return "="
else:
return "<"
def is_symbol(element):
#print("sybol",element)
res=False
symbol=["+","-","*","/","(",")"]
if element in symbol:
res=True
#print(res)
return res
def calculate(num1,symbol,num2): #定义简单的 4四则运算函数。
res=0
if symbol == "+":
res=num1+num2
elif symbol == "-":
res=num1-num2
elif symbol == "*":
res=num1*num2
elif symbol == "/":
res=num1/num2
return res
s1=init_action(s)
print(s1)
s2=main(s1)
print(s2)
print("eval 计算结果:{}".format(eval(s)))