作業 2, 模擬計算器開發:實現加減乘除及拓號優先順序解析用戶輸入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等類似公式後,必須自己解析裡面的(),+,-,*,/符 ...
作業 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等類似功能偷懶實現),運算後得出結果,結果必須與真實的計算器所得出的結果一致 2776672.6952380957
流程圖:
詳細代碼:

1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 import re 5 #b='1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' 6 #b='1 - 2 * ( (60-30 +(-40/5) * (9-2**5//3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)// (16-3*2) )' 7 #print(b) 8 9 def list_format(b):#格式化字元串函數 10 b=re.sub(' ','',b) 11 b=[i for i in re.split('(\-?\d+\.*\d*)',b) if i]#迴圈判斷,i 不為空,添加到列表 去空字元 -開頭加後面的數字 12 #print(b) 13 tmp_list=[]#定義一個臨時列表 14 while True: 15 if len(b)==0:break#如果列表為空就退出 16 emp=b.pop(0)#取出第一個元素 17 if (len(tmp_list)==0 and re.search('^\-\d*$',emp)) or (len(tmp_list)>0 and re.search('[\+\-\*\/\(\)]$',tmp_list[-1]) ):#判斷開頭與中間的負數 18 tmp_list.append(emp) 19 continue 20 sny_nl=[i for i in re.split('([\+\-\*\/\(\)])',emp) if i]#對運算符進行分割 21 22 for index, i in enumerate(sny_nl): 23 if i==' ':#去空格判斷 24 sny_nl.pop(index)#刪除空格項 25 tmp_list+=sny_nl 26 27 return tmp_list#返回列表 28 29 def Prioty(str_n,i):#比較優先順序函數 30 lev1=['+','-'] 31 lev2=['*','/'] 32 lev3=['('] 33 lev4=[')'] 34 if str_n in lev1: 35 if i in lev2 or i in lev3:#如果str_n 為+ - i 在2,3級時返回小於 36 return 1 37 else: 38 return 3 39 elif str_n in lev2:#如果str_n 為*/ i 在3級時返回小於 40 if i in lev3: 41 return 1 42 else: 43 return 3 44 elif str_n in lev3:#如果str_n 為(i 在4級時返回等於 45 if i in lev4: 46 return 2 47 else: 48 return 1 49 50 def sny(str):#判斷是否為運算符 51 sny_l=['+','-','*','/','**','//','(',')'] 52 tag=False 53 if str in sny_l: 54 return True#是運算符返回真 55 else: 56 return tag 57 58 def opera(num1,operation,num2):#運算函數 59 res=0 60 if operation=='+': 61 res=num1+num2 62 if operation=='-': 63 res=num1-num2 64 if operation=='*': 65 res=num1*num2 66 if operation=='/': 67 res=num1/num2 68 return res 69 70 def main(c):#主函數 71 numbe_list=[]#定義數字堆棧 72 sny_list=[]#定義運算符堆棧 73 for i in c: 74 if sny(i):#不是運算運 75 while True: 76 #print(numbe_list) 77 #print(sny_list) 78 if len(sny_list)==0:#如果列表為空,即第一個就無條件加入 79 sny_list.append(i) 80 break 81 prty=Prioty(sny_list[-1],i)# 82 if prty==1:#如果為一級 83 sny_list.append(i)#運算符繼續添加 84 break 85 elif prty==2:#如果為二級 86 sny_list.pop()#運算符要取出最後一個 87 break 88 elif prty==3:#如果為三級 89 operation=sny_list.pop()#運算符==取出最後一個 90 num2=numbe_list.pop()#取出數字二 91 num1=numbe_list.pop()#取出數字一 92 numbe_list.append(opera(num1,operation,num2))#數字列表添加運算的結果 93 #print(numbe_list,sny_list) 94 continue 95 else: 96 i = float(i)#轉為浮點數 97 numbe_list.append(i)#添加到數字列表 98 else: 99 operation=sny_list.pop()#運算符==取出最後一個 100 num2=numbe_list.pop()#取出數字二 101 num1=numbe_list.pop()#取出數字一 102 numbe_list.append(opera(num1,operation,num2))#數字列表添加運算的結果 103 #print(numbe_list,sny_list) 104 if len(sny_list):#如果運算符列表不為空再做一個運算 105 operation=sny_list.pop()#運算符==取出最後一個 106 num2=numbe_list.pop()#取出數字二 107 num1=numbe_list.pop()#取出數字一 108 numbe_list.append(opera(num1,operation,num2))#數字列表添加運算的結果 109 return numbe_list[0] 110 111 #程式開始 112 print("\033[35;1m歡迎使用python簡易計算器\033[0m".center(60,'=')) 113 if __name__ =='__main__': 114 while True: 115 b=input('請輸入你要計算的內容,按\033[31;1mQ/q\033[0m退出:') 116 if b=='q' or b=='Q': 117 exit() 118 #print(c) 119 try: 120 c=list_format(b)#運行輸入函數格式化字元串,存入列表 121 number=main(c) 122 print(number) 123 except Exception as e:#出錯可返回操作 124 print('輸入有誤,請重新輸入')View Code