功能介绍:
使用python实现简单的+-*/^()运算.
要求:
- 命令行输入表达式
- 输入10^(-10)~10^(10)整数,且运算结果也属于此范围。
- 实现简单的+-*/^()运算。
- 输出结果保留10位有效整数,且不足时不能补零。
思路:将任务分解,逐层实现括号里面的运算。实现加减运算——>递归计算所有加减运算。实现乘除运算——>递归实现所有乘除运算。乘方运算——>递归实现所有乘方运算。按优先级进行基本运算 乘方——乘除——加减。
代码实现:
import re
import sys
def power_function(s): # 计算乘方
if '^' in s:
ret = pow(float(s.split('^')[0]), float(s.split('^')[1]))
else:
pass
return ret
# print(power_function('10^-10'))
def remove_power(s): # 递归计算不含括号里面的乘方
if '^' not in s :
return s
else:
k = re.search(r'-?[\d\.]+\^-?[\d\.]+', s).group() # 提取乘方表达式
s = s.replace(k, str(power_function(k)))
return remove_power(s)
# print(remove_power('10^-10'))
def multiply_divide(s): #计算乘除
ret = float(s.split('*')[0]) * float(s.split('*')[1]) if '*' in s else float(s.split('/')[0]) / float(s.split('/')[1])
return ret
def remove_md(s): # 递归计算不含括号里面的乘除
if '*' not in s and '/' not in s:
return s
else:
k = re.search(r'-?[\d\.]+[*/]-?[\d\.]+', s).group() # 提取乘除表达式 如果两个负数运算 则变号
s = s.replace(k, '+' + str(multiply_divide(k))) if len(re.findall(r'-', k)) == 2 else s.replace(k, str(multiply_divide(k)))
return remove_md(s)
# print(remove_md('1*2*3'))
def add_sub(s): # 加减运算
l = re.findall('([\d\.]+|-|\+)', s)
if l[0] == '-':
l[0] = l[0] + l[1]
del l[1]
sum = float(l[0])
for i in range(1, len(l), 2):
if l[i] == '+' and l[i + 1] != '-':
sum += float(l[i + 1])
elif l[i] == '+' and l[i + 1] == '-':
sum -= float(l[i + 2])
elif l[i] == '-' and l[i + 1] == '-':
sum += float(l[i + 2])
elif l[i] == '-' and l[i + 1] != '-':
sum -= float(l[i + 1])
return sum
def basic_operation(s): # 计算加减乘除乘方
s = s.replace(' ', '')
return add_sub(remove_md(remove_power(s)))
def calculate(expression):
if not re.search(r'\([^()]+\)', expression):
return basic_operation(expression)
k = re.search(r'\([^()]+\)', expression).group()
expression = expression.replace(k, str(basic_operation(k[1:len(k) - 1])))
return calculate(expression)
def data_process(s):#非法数据格式检测 符合:返回True
s = s.replace(' ', '')
str_copy = s # 复制字符串 进行格式检测
# s = s.replace(' ', '')
str1 = "0123456789+-*/()^. "
for i in str_copy: #输入检测
if i not in str1:
print("INPUT ERROR")
return False
l1 = re.findall('\(', str_copy)#格式检测
l2 = re.findall('\)', str_copy)
# print(len(l1), len(l2))
if len(l1) != len(l2):
print("FORMAT ERROR")
return False
str_copy = str_copy.replace('(', '')
str_copy = str_copy.replace(')', '')
l_operate = []
str1 = '+_*/^=!&$#@<>~%'
for cx in str1: # 组合非法字符
for xy in str1:
l_operate.append(cx + xy)
for str_operate in l_operate:
if str_copy.find(str_operate) != -1: # 如果匹配到非法字符串 输出提示信息
print("FORMAT ERROR")
return False
if str_copy.find('/0') != -1:#运算检测
print("VALUE ERROE")
return False
# print(calculate(str_copy))
# print("success!!!!")
return True
def data_format_regular(number): #输出数据格式化
s = str(number)
new_str = s # 复制原字符串
# print(10 - len(new_str.split('.')[0]))
if float(new_str.split('.')[0]) == 0:
head_len = len(new_str.split('.')[0]) -1
else:
head_len = len(new_str.split('.')[0])
if head_len > 10 :
head_len = 10
tail_len = 10 - head_len
if len(new_str.split('.')[0]) >= 10 : # 输入限制原因 整数位<= 10 ;若=10 去除小数点
new_str = new_str[0:10]
# print(new_str)
s = new_str
elif len(new_str.split('.')[1]) > tail_len : # 根据整数位数截取小数部分(位数和 = 10)
str_tail = new_str.split('.')[1]
str_tail = str_tail[0:tail_len]
str_tail = str_tail[::-1]
# print(str_tail)
if str_tail[0] == '0':
count = 1
else:
count = 0
if count > 0:
for i in range(1, len(str_tail)):
if str_tail[i - 1] == '0' and str_tail[i] == '0':
count = count + 1
else:
# print(count)
break
str_tail = str_tail[count:len(str_tail)]
str_tail = str_tail[::-1]
s = new_str.split('.')[0] + "." + str_tail
else:
str_tail = new_str.split('.')[1]
if float(new_str.split('.')[1]) == 0:
s = new_str.split('.')[0]
else:
str_tail = str_tail[::-1]
print(str_tail)
if str_tail[0] == '0':
count = 1
else:
count = 0
if count > 0 :
for i in range(1 , len(str_tail)):
if str_tail[i-1] == '0' and str_tail[i] == '0':
count = count + 1
else:
print(count)
break
str_tail = str_tail[count:len(str_tail)]
if count == len(str_tail)-1:
s = new_str.split('.')[0] + str_tail
else:
str_tail = str_tail[::-1]
s = new_str.split('.')[0] + "." + str_tail
# print(s)
return s
# s1='12 + 3*2-(4+1) -15 /3 + 2^2 - (2^1)'
# s2 = '10^(9)'
# s3 = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
# s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
# s4 = '1 + 2 - 3 + 4'
# s5 = '1 + 2 - 3 + 1 / 3'
# s6 = '1 + + 2'
# s7 = '1 / 0'
# s8 = 'a + 1'
# if __name__ == "__main__":
# s = sys.argv[1]
# if data_process(s):
# print(data_format_regular(calculate(s)))
# s4 = s8
# if data_process(s4):
# # print(calculate(s2))
# print(data_format_regular(calculate(s4)))
if __name__ == "__main__":
s = sys.argv[1]
if data_process(s):
print(data_format_regular(calculate(s)))
# if data_process(s2):
# # print(calculate(s2))
# print(data_format_regular(calculate(s2)))