Python 3實現簡單計算機功能
用Python3寫一個計算機:實現準系統如+,-,*,/,^,
要注意的是:輸入含有括弧( ),小數點 .
思路就是逆波蘭運算式的演算法:
從中綴式的左端開始逐個讀取字元x,逐序進行如下步驟:
1.若x是運算元,將x直接壓入棧s2;
2.若x是運算子,則分情況討論:
若x是’(‘,則直接壓入棧s1;
若x是’)’,則將距離棧s1棧頂的最近的’(‘之間的運算子,逐個出棧,依次壓入棧s2,此時拋棄’(‘;
若x是除’(‘和’)’外的運算子,則再分如下情況討論:
若當前棧s1的棧頂元素為’(‘,則將x直接壓入棧s1;
若當前棧s1的棧頂元素不為’(‘,則將x與棧s1的棧頂元素比較,若x的優先順序大於棧s1棧頂運算子優先順序,則將x直接壓入棧s1。否者,將棧s1的棧頂運算子彈出,壓入棧s2中,直到棧s1的棧頂運算子優先順序別低於(不包括等於)x的優先順序,或棧s2的棧頂運算子為’(‘,此時再則將x壓入棧s1;
這代碼是剛接觸時候寫的。。自己都不忍心看下去了,有空再改改吧
#!//bin/python# -*- coding: UTF-8 -*-import sys '''date : 2017-09-08@author: vassago'''#get and update the datadef process_args(args): #合并,組成正確的小數 while(1): try: x=args.index('.') except : break args[x-1]+=args[x] args[x-1]+=args[x+1] del args[x] del args[x] #合并,組成正確的多位元 llen =len(args) i=1 while(i<llen): if(args[i-1]=='(' or args[i-1]==')' or args[i-1]=='+' or args[i-1]=='-' or args[i-1]=='*' or args[i-1]=='/' or args[i-1]=='^'): i+=1 continue if(args[i]!='(' and args[i]!=')' and args[i]!='+' and args[i]!='-' and args[i]!='*' and args[i]!='/' and args[i]!='^'): args[i-1]+=args[i] del args[i] llen-=1 i-=1 i+=1 return argsdef get_nibolan_list(args): #get nibolan list pri={'(':0,')':0, '+':1,'-':1, '*':2,'/':2,'^':3} stack1,stack2=[],[] for x in args: if(x=='main.py' or x==' '): continue if(x=='('): stack1.append(x) elif(x==')'): top=stack1.pop() while(top!='('): stack2.append(top) top=stack1.pop() elif(x=='+' or x=='-' or x=='*' or x=='/' or x=='^'): if(len(stack1)==0): stack1.append(x) else: top1=stack1.pop() if(pri[x]>pri[top1]): stack1.append(top1) stack1.append(x) else: while(1): if(pri[x]>pri[top1]): stack1.append(top1) break stack2.append(top1) if(len(stack1)==0): break top1=stack1.pop() stack1.append(x) else: stack2.append(x) while(len(stack1)!=0): stack2.append(stack1.pop()) nibolan=[] while(len(stack2)!=0): nibolan.append(stack2.pop()) #print(nibolan) return nibolandef process_nibolan(nibolan): #output the answer stack,fla=[],1 while(1): top=nibolan.pop() if(top=='+' or top=='-' or top=='*' or top=='/' or top=='^'): try: y=float(stack.pop()) x=float(stack.pop()) except IndexError: print('FORMAT ERROR') fla=0 break except ValueError: print('INPUT ERROR') fla=0 break try: if(top=='+'): stack.append(x+y) if(top=='-'): stack.append(x-y) if(top=='*'): stack.append(x*y) if(top=='/'): stack.append(x/y) if(top=='^'): stack.append(x**y) except ValueError : print('Value Error') fla=0 break while(len(stack)!=0): nibolan.append(stack.pop()) else: stack.append(top) if(len(nibolan)==0): break return stack[0]if __name__ == '__main__': string="" for x in sys.argv: if(x=="main.py" or x==' '): continue string+=x args=list(string) print (process_nibolan(get_nibolan_list(process_args(args)))
測試時:
採用命令列輸入
python main.py "1+2^2-3*(2-1)/3"
輸出:
4.0