import re
from functools import reduce
'''
分析:
1.用户输入
2.判断表达式是否正确
3.计算
1)通过正则获取(。。。)进行计算并替换(。。。)
2)循环1)直到未找到则标记为最后一层,计算结果并返回
计算中的注意事项:
注意两个数的前后位置,不要颠倒了
查找含有负数的符号,进行转换(查找负数符号最前面的-或+进行倒换,并去掉负数符号)
4.显示结果
'''
def count(first,symbol,second):
'''
计算两个数的运算值
:param first: 第一个数
:param symbol: 运算符
:param second: 第二个数
:return:
'''
if symbol == '*':
return float(first) * float(second)
elif symbol=='/':
return float(first) / float(second)
elif symbol=='+':
return float(first) + float(second)
elif symbol == '-':
return float(first) - float(second)
def count_express(group):
'''
计算一个字符表达式的值
:param group: 要运算的字符
:return:
'''
result = re.findall('[0-9]+[.0-9]*|[^0-9]', group)
list1 = list(reversed(list(result)))
first = ''
symbol = '+'
second = '0'
first = list1.pop()
stack =[]
# '1+2*(2+3*4-4)'
if first == '-':
first += list1.pop()
while len(list1) != 0:
symbol = list1.pop()
second = list1.pop()
if symbol == '-' or symbol == '+':
stack.append(first)
stack.append(symbol)
first = second
continue
first = str(count(first, symbol, second))
while len(stack) > 1:
symbol = stack.pop()
second = stack.pop()
first = count(second, symbol, first)
return str(first)
def group_count(express):
'''
计算表达式值
:param express: 字符表达式
:return:
'''
while True:
pattern = r'([^()]+)'
pat = re.compile(pattern)
group = pat.search(express)
result = []
# 判断是否找到()
flag = True
if group != None:
group = group.group()
group = group.replace('(','').replace(')','')
else:
group = express
flag = False
result = count_express(group)
# 如果是最后一层,直接返回值
if flag is False:
return result
# 将express中找到(..)的运算结果进行替换
express = pat.sub(result,express)
express = replace_symbol(express)
print(express)
def replace_symbol(express):
'''
将负数转正
:param express:
:return:
'''
split_list = re.split('[+*/-]-', express)
b = split_list[0]
# 字符反转
c = reduce(lambda x, y: y + x, b)
# 查找离要负号位最近是(+-)进行替换
d = re.search('[+-]', c)
f = d.group()
m = '+' if f == '-' else '-'
list_str = list(c)
list_str[d.span()[0]] = m
list_str.reverse()
c = ''.join(list_str)
return c +express[len(c)]+ split_list[1]
def check_express(express):
'''
校验输入的表达式是否正确
:param express: 字符表达式
:return:
'''
pattern1 = '[^0-9+*/.()-]|[^0-9][+/*.]|[0-9][(]|^[+/*.]|[+/*.]$'
result = re.search(pattern1,express)
return result
def input_express():
# express = input("请输入(只能包含0-9+-*/.()字符):")
express = '-1+2*3-4/(-10*2)-3'
express = re.sub(' ', '', express)
result = check_express(express)
if result != None:
span = str(result.span())
group = str(result.group())
print('输入了错误的字符或表达式格式不对,所在位置:%s,错误字符:%s' % (span, group))
sys.exit(0)
return express
if __name__ == '__main__':
express = input_express()
result = group_count(express)
print('结果:%s' %result)