编写了一个计算器程序,但是输出结果很奇怪,希望能改正
operators = {
"(": 1,
")": 1,
"+": 2,
"-": 2,
"*": 3,
"/": 3,
"%": 3,
"^": 4,
}
expression = input("input expression:")
def calculate(expression):
operands = []
operators = []
# 检查表达式是否合法
if expression[0] in operators or expression[-1] in operators:
return "Hint:the expression is wrong in format."
for i in range(1, len(expression)):
if expression[i] in operators and expression[i - 1] in operators:
return "Hint:the expression is wrong in format."
negative = False
for x in expression:
# 如果字符是数字,则将它压入操作数栈中
if x.isdigit():
if negative:
operands.append(-int(x))
negative = False
else:
operands.append(int(x))
# 如果字符是运算符,则根据优先级规则压入或弹出运算符栈
elif x in operators:
if x == "(":
operators.append(x)
elif x == ")":
while operators[-1] != "(":
operator = operators.pop()
b = operands.pop()
a = operands.pop()
if operator == "+":
operands.append(a + b)
elif operator == "-":
operands.append(a - b)
elif operator == "*":
operands.append(a * b)
elif operator == "/":
operands.append(a / b)
elif operator == "%":
operands.append(a % b)
elif operator == "^":
operands.append(a ** b)
operators.pop()
# 如果遇到其他运算符,则弹出运算符栈中优先级大于或等于当前运算符的运算符
else:
while operators and operators[-1] != "(" and operators.index(operators[-1]) >= operators.index(x):
operator = operators.pop()
b = operands.pop()
a = operands.pop()
if operator == "+":
operands.append(a + b)
elif operator == "-":
operands.append(a - b)
elif operator == "*":
operands.append(a * b)
elif operator == "/":
operands.append(a / b)
elif operator == "%":
operands.append(a % b)
elif operator == "^":
operands.append(a ** b)
# 将当前运算符压入运算符栈中
operators.append(x)
elif x == "-":
negative = True
return operands.pop()
result = calculate(expression)
print(result)
1+1=1或1+3=3
建立一个数字栈和一个符号栈,遍历输入值里面的所有字符
希望最后运行界面大概如下,如果表达式格式有误会提示
input expresion:
-2*(3+5)+2^3/4=
-14
continue or not(y,n)?
y
input expression:
2 3 5+6=
Hint:the expression is wrong in format.
代码有不少问题
给你整理了一份:
import re
def caculator(eq):
format_list = eq_format(eq) # 把字符串变成格式化列表形式
s_eq = simplify(format_list) # 去括号,得到无括号的一个格式化列表
ans = calculate(s_eq) # 计算最终结果
if len(ans) == 2: # 判断最终结果为正数还是负数
ans = -float(ans[1])
else:
ans = float(ans[0])
return ans
def eq_format(eq):
'''
:param eq: 输入的算式字符串
:return: 格式化以后的列表,如['60','+','7','*','8']
'''
format_list = re.findall('[\d\.]+|\(|\+|\-|\*|\/|\)',eq)
return format_list
def simplify(format_list):
'''
:param format_list: 输入的算式格式化列表如['60','+','7','*','8']
:return: 通过递归去括号,返回简化后的列表
'''
bracket = 0 # 用于存放左括号在格式化列表中的索引
count = 0
for i in format_list:
if i == '(':
bracket = count
elif i == ')':
temp = format_list[bracket + 1 : count]
# print(temp)
new_temp = calculate(temp)
format_list = format_list[:bracket] + new_temp + format_list[count+1:]
format_list = change(format_list,bracket) # 解决去括号后会出现的-- +- 问题
return simplify(format_list) # 递归去括号
count = count + 1
return format_list
def calculate(s_eq):
'''
:param s_eq: 不带括号的格式化列表
:return: 计算结果
'''
if '*' or '/' in s_eq:
s_eq = remove_multiplication_division(s_eq)
if '+' or '-' in s_eq:
s_eq = remove_plus_minus(s_eq)
return s_eq
def remove_multiplication_division(eq):
'''
:param eq: 带有乘除号的格式化列表
:return: 去除了乘除号的格式化列表
'''
count = 0
for i in eq:
if i == '*':
if eq[count+1] != '-':
eq[count-1] = float(eq[count-1]) * float(eq[count+1])
del(eq[count])
del(eq[count])
elif eq[count+1] == '-':
eq[count] = float(eq[count-1]) * float(eq[count+2])
eq[count-1] = '-'
del(eq[count+1])
del(eq[count+1])
eq = change(eq,count-1)
return remove_multiplication_division(eq)
elif i == '/':
if eq[count+1] != '-':
eq[count-1] = float(eq[count-1]) / float(eq[count+1])
del(eq[count])
del(eq[count])
elif eq[count+1] == '-':
eq[count] = float(eq[count-1]) / float(eq[count+2])
eq[count-1] = '-'
del(eq[count+1])
del(eq[count+1])
eq = change(eq,count-1)
return remove_multiplication_division(eq)
count = count + 1
return eq
def remove_plus_minus(eq):
'''
:param eq: 只带有加减号的格式化列表
:return: 计算出整个列表的结果
'''
count = 0
if eq[0] != '-':
sum = float(eq[0])
else:
sum = 0.0
for i in eq:
if i == '-':
sum = sum - float(eq[count+1])
elif i == '+':
sum = sum + float(eq[count+1])
count = count + 1
if sum >= 0:
eq = [str(sum)]
else:
eq = ['-',str(-sum)]
return eq
def change(eq,count):
'''
:param eq: 刚去完括号或者乘除后的格式化列表
:param count: 发生变化的元素的索引
:return: 返回一个不存在 '+-' ,'--'类的格式化列表
'''
if eq[count] == '-':
if eq[count-1] == '-':
eq[count-1] = '+'
del eq[count]
elif eq[count-1] == '+':
eq[count-1] = '-'
del eq[count]
return eq
express = "1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))"
result =caculator(express)
print(result)
这样写会产生优先级问题(如1+2*3=9)。其实可以用Python的内建函数eval
a=“1+2*3”
res=eval(a)
很轻松就解决运算问题了,而只需要专注于解决输入不规范问题
eval函数会不会
兄弟,你先把字典的operators和函数内列表的operators改成不同的变量名,其他位置也同步更改,如果还报错,继续回答。
使用try except。来捕捉eval错误,如果不规范就会被捕捉到错误
你这么写就是按顺序执行的,没有优先级了
# 哈喽,同学你好,如果你希望输入一个数字,并用程序对这个数字进行计算,可采用eval(input(<输入提示字符串>))的组合
print("结果是:",eval(input("请输入算式:")))
后面你想要的控制台结果,加一个判断语句就可以完美解决啦