'''
******************** 請計算表達式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ********************
(-40.0/5) 計算後爲 (-8.0) ;則式子化簡爲: 1-2*((60-30+(-8.0)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
(9-2*5/3+7/3*99/4*2998+10*568/14) 計算後爲 173545.88095238098 ;則式子化簡爲: 1-2*((60-30+(-8.0)*173545.88095238098)-(-4*3)/(16-3*2))
(60-30+(-8.0)*173545.88095238098) 計算後爲 (-1388337.0476190478) ;則式子化簡爲: 1-2*((-1388337.0476190478)-(-4*3)/(16-3*2))
(-4*3) 計算後爲 (-12.0) ;則式子化簡爲: 1-2*((-1388337.0476190478)-(-12.0)/(16-3*2))
(16-3*2) 計算後爲 10.0 ;則式子化簡爲: 1-2*((-1388337.0476190478)-(-12.0)/10.0)
((-1388337.0476190478)-(-12.0)/10.0) 計算後爲 (-1388335.8476190479) ;則式子化簡爲: 1-2*(-1388335.8476190479)
最後結果爲: 2776672.6952380957python
'''正則表達式
基於遞歸和正則表達式實現的,源碼以下:express
# Author: Alan import re #實現輸入數學式子(python裏),計算其結果,相似計算器。思路以下: #1.去括號:先計算最裏層括號內的表達式(正則抓出)並計算出值,而後完成替換,最後循環此步驟(遞歸),直到沒有括號或其內無表達式 #2.表達式(沒有括號的干擾)計算:按運算符優先級(正則抓出)依次計算出值(遞歸),而後完成替換,最後會返回一個值(負數則用小括號括起) #3.支持:python **,%,//等運算,小括號,中括號,及大括號(其實原理是同樣的,正則都相似) #4.坑:替換時若是用re.sub,因爲式子包含一些特殊字符須要轉義才能替換,然而我用的是replace #5.輸入:若是不是位於表達式的開頭的負數請用小括號括起,避免符號混亂 def count_ex(list,strx): #計算一次結果 負數用()括起來 list_left=re.sub('[\(\)]*','',list[0]) list_right=re.sub('[\(\)]*','',list[2]) list_sym=list[1] list_str=''.join(list) if list_sym=='**': num=float(list_left)**float(list_right) sym_str=str(num) if num>0 else '(%s)'%num #計算結果 return strx.replace(list_str,sym_str,1) elif list_sym=='//': num = float(list_left) // float(list_right) sym_str = str(num) if num > 0 else '(%s)' % num # 計算結果 return strx.replace(list_str,sym_str,1) elif list_sym=='%': num = float(list_left) % float(list_right) sym_str = str(num) if num > 0 else '(%s)' % num # 計算結果 return strx.replace(list_str,sym_str,1) elif list_sym=='/': num = float(list_left) / float(list_right) sym_str = str(num) if num > 0 else '(%s)' % num # 計算結果 return strx.replace(list_str,sym_str,1) elif list_sym=='*': num = float(list_left) * float(list_right) sym_str = str(num) if num > 0 else '(%s)' % num # 計算結果 return strx.replace(list_str,sym_str,1) elif list_sym=='+': num = float(list_left) + float(list_right) sym_str = str(num) if num > 0 else '(%s)' % num # 計算結果 return strx.replace(list_str,sym_str,1) elif list_sym=='-': num = float(list_left) - float(list_right) sym_str = str(num) if num > 0 else '(%s)' % num # 計算結果 return strx.replace(list_str,sym_str,1) def regex_split(str,pattern): #處理算術運算符 list = re.findall(pattern, str) if not list: return str else: str = count_ex(list[0], str) return regex_split(str,pattern) def bracket(strx): #處理括號中的內容,順序小括號,中括號,大括號。結束條件沒有中括號及大括號和小括號內無表達式(遞歸) regex_bracket=[ '\((?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\)', '\[(?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\]', '\{(?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\}' ] for i in regex_bracket: list=re.findall(i, strx) if not list:continue else: strx1=deal_expression(list[0][1:-1])#去掉最外層括號並處理此表達式 strx=strx.replace(list[0], strx1, 1)#完成替換 print(list[0],'計算後爲',strx1,';則式子化簡爲:',strx) res_end=re.findall( '(\{|\[|\((?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\))', strx) if not res_end:return strx#結束條件 return bracket(strx) def deal_expression(strx): #處理表達式,運算符優先級,先**,在//,%,/,*,最後+,- rank_sym_pattern=[ '(\([\-]?\d+\.?\d*\)|^\-\d+\.?\d*|\d+\.?\d*)(\*\*)(\([\-]?\d+\.?\d*\)|\d+\.?\d*)', '(\([\-]?\d+\.?\d*\)|^\-\d+\.?\d*|\d+\.?\d*)(\%|\/\/|\*|\/)(\([\-]?\d+\.?\d*\)|\d+\.?\d*)', '(^\-\d+\.?\d*|\d+\.?\d*|\([\-]?\d+\.?\d*\))(\+|\-)(\([\-]?\d+\.?\d*\)|\d+\.?\d*)' ] for i in rank_sym_pattern: strx=regex_split(strx, i) return strx def run(): while True: ex = input('ex>>>:').strip() if not ex: continue if ex == 'q': break ex=re.sub('\s','',ex) print('最後結果爲:',deal_expression(bracket(ex)).strip('()')) if __name__ == '__main__': run() # expression='22//2+1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-((-4)*3)/(16-3*2))' # print(deal_expression(bracket(expression)))
轉載請註明出處!!!!!!!!!!!!!!!!!!spa