基于Python语言的逆波兰式简易计算器

import math

# merge
def merge(arg):
    # merge the deciaml
    while (True):
        try:
            x=arg.index('.')
        except:
            break
        arg[x-1]+=arg[x]
        arg[x-1]+=arg[x+1]
        del arg[x]
        del arg[x]

    # combined trigonometric function
    while True:
        try:x=arg.index('i')
        except:
            break
        arg[x-1]+=arg[x]
        arg[x-1]+=arg[x+1]
        del arg[x]
        del arg[x]

    while True:
        try:x=arg.index('o')
        except:
            break
        arg[x-1]+=arg[x]
        arg[x-1]+=arg[x+1]
        del arg[x]
        del arg[x]

    while True:
        try:x=arg.index('a')
        except:
            break
        arg[x-1]+=arg[x]
        arg[x-1]+=arg[x+1]
        del arg[x]
        del arg[x]

    while True:
        try:x=arg.index('q')
        except:
            break
        arg[x-1]+=arg[x]
        arg[x-1]+=arg[x+1]
        arg[x-1]+=arg[x+2]
        del arg[x]
        del arg[x]
        del arg[x]
    # combined multidigit
    y=len(arg)
    i=1
    while (i<y):
        if arg[i-1]=='(' or arg[i-1]==')' or arg[i-1]=='+' or arg[i-1]=='-' or arg[i-1]=='*' or arg[i-1]=='/' or arg[i-1]=='^' or arg[i-1]=='sin' or arg[i-1]=='cos' or arg[i-1]=='tan' or arg[i-1]=='sqrt':
            i+=1
            continue

        if arg[i]!='(' and arg[i]!=')' and arg[i]!='+' and arg[i]!='-' and arg[i]!='*' and arg[i]!='/' and arg[i]!='^' and arg[i]!='sin' and arg[i]!='cos' and arg[i]!='tan' and arg[i]!='sqrt':
            arg[i-1]+=arg[i]
            del arg[i]
            y-=1
            i-=1
        i+=1

    return arg


#get the list of Reverse Polish Notation
def get_RPN(arg):
    Pri={'(':0,')':0,'+':1,'-':1,'*':2,'/':2,'^':3}
    #add symbol to Stack1
    #add the list of Reverse Polish Notation to Stack2
    Stack1=[]
    Stack2=[]
    for z in arg:
        if z=='sin' or z=='cos' or z=='tan' or z=='sqrt':
            Stack1.append(z)
        elif z=='(':
            Stack1.append(z)
        elif z==')':
            top=Stack1.pop()
            while(top!='('):
                Stack2.append(top)
                top=Stack1.pop()
            if Stack1[-1]=='sin' or Stack1[-1]=='cos' or Stack1[-1]=='tan' or Stack1[-1]=='sqrt':
                Stack2.append(Stack1.pop())
        elif z=='+' or z=='-' or z=='*' or z=='/' or z=='^':
            if len(Stack1)==0:
                Stack1.append(z)
            else:
                top1=Stack1[-1]
                if Pri[z]>Pri[top1]:
                    Stack1.append(z)
                else:
                    while(1):
                        if Pri[z]>Pri[top1]:
                            break
                        Stack2.append(top1)
                        Stack1.pop()
                        if len(Stack1)==0:
                            break
                        top1=Stack1[-1]
                    Stack1.append(z)
        else:
            Stack2.append(z)

    while(len(Stack1)!=0):
        Stack2.append(Stack1.pop())

    RPN=Stack2
    return RPN



#Calculate the value of the Reverse Polish Notation
def process_RPN(RPN):
    if len(RPN)==0:
        return 0
    if len(RPN)==1:
        return RPN[0]

    p=len(RPN)
    w=0
    while w<p:
        if RPN[w]=='+':
            RPN[w-2]=float(RPN[w-2])
            RPN[w-1]=float(RPN[w-1])
            RPN[w-2]+=RPN[w-1]
            del RPN[w-1]
            del RPN[w-1]
            w-=2
            p-=2
        elif RPN[w]=='-':
            RPN[w-2]=float(RPN[w-2])
            RPN[w-1]=float(RPN[w-1])
            RPN[w-2]-=RPN[w-1]
            del RPN[w-1]
            del RPN[w-1]
            w-=2
            p-=2
        elif RPN[w]=='*':
            RPN[w-2]=float(RPN[w-2])
            RPN[w-1]=float(RPN[w-1])
            RPN[w-2]*=RPN[w-1]
            del RPN[w-1]
            del RPN[w-1]
            w-=2
            p-=2
        elif RPN[w]=='/':
            RPN[w-2]=float(RPN[w-2])
            RPN[w-1]=float(RPN[w-1])
            try:
                a=RPN[w-2]/RPN[w-1]
            except ZeroDivisionError:
                print('Zero Division Error')
                break
            finally:
                RPN[w-2]=a
                del RPN[w-1]
                del RPN[w-1]
            w-=2
            p-=2
        elif RPN[w]=='^':
            RPN[w-2]=float(RPN[w-2])
            try:
                RPN[w-1]=int(RPN[w-1])
            except ValueError:
                print('Value Error')
                break
            finally:
                RPN[w-2]**=RPN[w-1]
                del RPN[w-1]
                del RPN[w-1]
            w-=2
            p-=2
        elif RPN[w]=='sin':
            RPN[w-1]=float(RPN[w-1])
            RPN[w-1]=math.sin(RPN[w-1])
            del RPN[w]
            w-=1
            p-=1
        elif RPN[w]=='cos':
            RPN[w-1]=float(RPN[w-1])
            RPN[w-1]=math.cos(RPN[w-1])
            del RPN[w]
            w-=1
            p-=1
        elif RPN[w]=='tan':
            RPN[w-1]=float(RPN[w-1])
            try:
                RPN[w-1]=math.tan(RPN[w-1])
            except ZeroDivisionError:
                print('Zero Division Error')
            finally:
                del RPN[w]
            w-=1
            p-=1
        elif RPN[w]=='sqrt':
            RPN[w-1]=float(RPN[w-1])
            try:
                RPN[w-1]=math.sqrt(RPN[w-1])
            except:
                print('Negative Numbers are not allowed')
            finally:
                del RPN[w]
            w-=1
            p-=1

        w+=1

        if p==1:
            return RPN[0]



def main():
    while True:
        arg=list(str(input()))
        print('Reverse Polish Notation: ', get_RPN(merge(arg)), '\n')
        print('Result: ', process_RPN(get_RPN(merge(arg))))

if __name__ == '__main__':
  main()



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值