zoukankan      html  css  js  c++  java
  • python 利用栈实现复杂计算器


    #第五周的作业--多功能计算器
    #1.实现加减乘除及括号的优先级的解析,不能使用eval功能,print(eval(equation))
    #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等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致
    ''' 1.自左向右扫描表达式,凡是遇到操作数一律进操作数栈。
    2.当遇到运算符时,如果它的优先级比运算符栈栈顶元素的优先级低就入栈。反之,取出栈顶运算符和操作数栈顶的两个连续操作数运算,并将结果存入操作数栈,然后继续比较该运算符与栈顶的运算符的优先级。
    3.左括号一律进运算符栈,右括号一律不进运算符栈,取出栈顶运算符和操作数栈顶的两个连续操作数运算,并将结果存入操作数栈,直到取出左括号为止。

    Nyah-NyahLeft hug

    #给一个点,我们能够根据这个点知道一些内容
    class Node(object):
        def __init__(self,val): #定位的点的值和一个指向
            self.val=val    #指向元素的值
            self.next=None   #指向的指针
    class Stack(object):
        def __init__(self):
            self.top=None #初始化最开始的位置
        def peek(self):  #获取栈顶的元素
            if self.top!=None:  #如果栈顶不为空
                return self.top.val  #返回栈顶元素的值
            else:
                return None
        def push(self,n):#添加到栈中--入栈
            n=Node(n)  #实例化节点
            n.next=self.top  #顶端元素传值给一个指针
            self.top=n    #新入栈的节点作为栈顶元素
            return n.val
        def pop(self):  #出栈
            if self.top == None:
                return None
            else:
                tmp=self.top.val
                self.top=self.top.next  #栈顶下移一位
                return tmp
    
    
    # if __name__=="__main__":
    #     s=Stack()
    #     s.push(1)
    #     s.push(2)
    #     s.push(3)
    #
    #     print(s.pop())
    #     print(s.pop())
    #     print(s.pop())
    python 实现栈
    下面是计算器的代码,引用了上面的栈的模块
    #_*_coding:utf-8_*_
    #第五周的作业--多功能计算器
    
    import string
    import re
    from stack_test import Node,Stack
    # 定义加法运算
    def add(num1,num2):
        return num1+num2
    # 定义减法运算
    def sub(num1,num2):
        return num1-num2
    # 定义乘法运算
    def mult(num1,num2):
        return num1*num2
    # 定义除法运算
    def div(num1,num2):
        return num1/num2
    # 定义运算的操作
    operation={
        "+":add,
        "-":sub,
        "*":mult,
        "/":div
    }
    #判断一个字符串是否是数字
    def is_number(s):
        try:
            float(s)
            return True
        except ValueError:
            pass
    
        try:
            import unicodedata
            unicodedata.numeric(s)
            return True
        except (TypeError, ValueError):
            pass
    
        return False
    
    # 定义运算符的优先级别
    weight={
        '(':3,
        '*':2,
        '/':2,
        '+':1,
        '-':1,
        None:0
    }
    
    # 进行运算
    num1=0
    num2=0
    result=0#用于表示计算的
    data_stack=Stack()#实例化的一个数栈,存放数
    oper_stack=Stack()#实例化的一个符号栈,存放+-*/()
    def deal_data():
        p=oper_stack.pop()#把运算符出栈
        num2=float(data_stack.pop())
        num1=float(data_stack.pop())
        result=operation[p](num1,num2)
        print("%s %s %s临时结果:%s"%(num1,p,num2,result))
        print("把计算的结果%s继续存入数栈中"%result)
        data_stack.push(result)
        return result
    
    while True:
        equation=input("请输入计算的式子(*提示英文状态下):")
    
        # 对输入的算式字符串进行解析,eg:3*5,(99.8-52)*7+6-1.2*41
        #1.2-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
    
        while equation:
            cur=re.search(r'((^d+.?d*)|(^(-d+.?d*)|(|)|+|-|*|/)',equation).group()
            print("----->",cur)
            if "(-" in cur:#考虑到负数的情形,如(-5.2)
                # 一分为二,"("与"-4"
                # 把左括号存入到符号栈中
                bracket=cur[0]
                print("----->",bracket)
                print("将%s存入到符号栈中"%bracket)
                oper_stack.push(bracket)
                equation=equation[1:]
                print("剩余的equation:",equation)
    
                # 把负数存入到符号栈中
                num=cur[1:]
                print("----->",num)
                print("将%s存入到数栈中"%num)
                data_stack.push(num)
                equation=equation[len(num):]
                print("剩余的equation:",equation)
            else:#非负情形
                lenth=len(cur)
                if is_number(cur):#数字则存入数栈
                    print("将 %s 存入数栈data_stack"%cur)
                    data_stack.push(cur)
                else:#非数字的符号
                    if cur=="(":#左括号一律入栈
                        print("将%s存入到符号栈中"%cur)
                        oper_stack.push(cur)
                    elif cur==")":#右括号则--将取两个数进行运算
                        deal_data()#处理数据的运算
                        #(12-5*8)再次判断“(”是否是符号栈的栈顶
                        while oper_stack.peek()!="(":
                            deal_data()
                        oper_stack.pop()#把左括号出栈
    
                    else:#运算符
                        if oper_stack.peek()==None:#符号栈为空
                            print("将%s存入到符号栈中"%cur)
                            oper_stack.push(cur)
                        else:#符号栈不为空
    
                            if weight[cur]>weight[oper_stack.peek()]:#当前符号优先级“高于”栈顶元素的优先级
                                print("将%s存入到符号栈中"%cur)
                                oper_stack.push(cur)
                            else:#当前符号优先级“等于|低于”符号栈栈顶元素的优先级
                                if oper_stack.peek()=="(":
                                    print("将%s存入到符号栈中"%cur)
                                    oper_stack.push(cur)
                                else:
                                    deal_data()
                                    while weight[cur]==weight[oper_stack.peek()]:
                                        deal_data()
                                    print("将%s存入到符号栈中"%cur)
                                    oper_stack.push(cur)
    
                equation=equation[lenth:]
                print("剩余的equation:",equation)
        # 把算式逐个拆解完了,最后处理栈中还剩余的数据
        result=deal_data()
        while oper_stack.peek()!=None:
            result=deal_data()
    
        print("计算的结果为:33[31;1m%s33[0m"%result)
    
    
    python利用栈实现复杂计算器
  • 相关阅读:
    java 日志体系
    java mail 接收邮件
    Spring 事物Transaction
    Spring 文件上传MultipartFile 执行流程分析
    centos7安装Elasticsearch7
    centos7安装docker笔记
    docker安装
    redis
    springboot+redis+nginx+分布式session
    tomcat程序和webapp分离
  • 原文地址:https://www.cnblogs.com/jean925/p/7715973.html
Copyright © 2011-2022 走看看