作業需求:
1、實現加減乘除及拓號優先級解析
2、用戶輸入
1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
等類似公式后
3、必須自己解析里面的(),+,-,*,/符號和公式(不能調用eval等類似功能偷懶實現),
4、運算后得出結果,結果必須與真實的計算器所得出的結果一致
1)流程圖
首先,根據計算符號的優先級考慮,帶有括號的優先級最高,需要優先計算括號內的式子,計算完括號內的式子之后,破除括號,再進行加減乘除的運算。在四則運算中,加減運算是一個優先級的,乘除運算是一個優先級的,那么我們就可以先行計算乘除,將整個式子中的乘除全部計算完成以后,再次進行加減的計算,最終可以得到運算的結果
2、程序會判斷用戶輸入的表達式是否符有效並給出相應提示
2、用戶在主界面中輸入:"q"程序會退出
3、程序通過eval函數計算出正確計算結果
二、具體實現
#-*- Coding:utf-8 -*- # Author: D.Gray import re,sys ''' 要求: 1\實現加減乘除及拓號優先級解析 2\用戶輸入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) 等類似公式后,必須自己解析里面的(),+,-,*,/符號和公式(不能調用eval等類似功能偷懶實現), 運算后得出結果,結果必須與真實的計算器所得出的結果一致 ''' def compute_mul_div(mg): ''' 定義一個乘除函數 :param mg: :return: ''' num = mg[0] # -40/5 match = re.search("\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*",num) if not match: return content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',num).group() if len(content.split('*')) > 1: v1,v2 = content.split('*') value = float(v1) * float(v2) # print('v1>>>%s and v2>>>%s'%(str(v1),str(v2))) # print('computer_mul:%s and %s'% (str(content),str(value))) else: v1, v2 = content.split('/') value = float(v1) / float(v2) # print('v1>>>%s and v2>>>%s' % (str(v1), str(v2))) # print('computer_del:%s and %s' % (str(content),str(value))) pur,suf = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*',num,1) new_str = '%s%s%s'%(pur,value,suf) mg[0] = new_str #print('pur>>>%s value>>>%s uer>>>%s new_str>>>%s' % (pur, value,suf,new_str)) compute_mul_div(mg) def compute_add_sub(mg): ''' 運算表達式加減函數 :param mg: :return: ''' while True: if mg[0].__contains__('+-') or mg[0].__contains__('++') or mg[0].__contains__('-+') or mg[0].__contains__('--'): mg[0] = mg[0].replace('+-', '-') # 將-替換掉+- mg[0] = mg[0].replace('++', '+') # 將+替換掉++ mg[0] = mg[0].replace('-+', '-') # 將-替換掉-+ mg[0] = mg[0].replace('--', '+') # 將+替換掉-- else: break if mg[0].startswith('-'): # 如果arg的第0個元素是以-開頭 mg[1] += 1 # arg的第一個元素自加1 mg[0] = mg[0].replace('-', '&') mg[0] = mg[0].replace('+', '-') mg[0] = mg[0].replace('&', '+') # 將-變+,+變- mg[0] = mg[0][1:] # 將arg中第0個元素中前面多出來的符號去掉 num = mg[0] # -40/5 match = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*',num) if not match: return content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*',num).group() if len(content.split('+')) > 1: v1, v2 = content.split('+') value = float(v1) + float(v2) # print('v1>>>%s and v2>>>%s' % (str(v1), str(v2))) # print('computer_add:%s and %s' % (str(content),str(value))) else: v1, v2 = content.split('-') value = float(v1) - float(v2) # print('v1>>>%s and v2>>>%s' % (str(v1), str(v2))) # print('computer_sub:%s and %s' % (str(content),str(value))) pur,suf = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*',num,1) new_str = '%s%s%s'%(pur,value,suf) mg[0] = new_str compute_add_sub(mg) def calate(match_group): ''' 計算表達式函數 :param match_group: :return: ''' mg = [match_group.strip('()'),0] # mg = ['-40/5'] compute_mul_div(mg) #調用乘除運算函數 compute_add_sub(mg) #調用加減運算函數 if divmod(mg[1],2)[1] == 1: result = float(mg[0]) result *= -1 #print('divmod_result:%s'%result) else: result = float(mg[0]) #print('in the calator-new_str():%s'%mg) return result def kuohao(calculate): ''' 取出表達式中括號函數 :param calculate: :return: ''' while True: match = re.search('\([^()]+\)',calculate) #使用正則表達式 取出優先級最高的括號 並計算 if match: #如果表達式中有括號 match_group = match.group() # match_result = calate(match_group) #調用計算函數 calculate = calculate.replace(match_group,str(match_result)) #將括號計算后的結果替換原參數 else: #若表達式中沒有括號 calate(calculate) break return calate(calculate) print('\033[33m 歡迎使用計算器 :\033[0m'.center(50,'-')) print('例:1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))') while True: calculate_input = input('\033[32m請輸入計算的表達式 | (退出:q)>>>\033[0m') calculate_input = re.sub('\s*','',calculate_input) if calculate_input == 'q': exit('程序退出') if len(calculate_input) == 0: continue if re.search('[^\d\+\-\*/\(\)]',calculate_input): #使用正則表達式判斷用戶輸入是否是數字、"+-*/"、"()" print('\033[31m 輸入錯誤,請重新輸入!!!\033[0m') else: result = kuohao(calculate_input) #調用去除括號的函數 print('\033[34m 計算結果>>>%s\033[0m'%result) print('\033[35m 正確結果>>>%s\033[0m' % eval(calculate_input))