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("計算的結果為:\033[31;1m%s\033[0m"%result)

python利用棧實現復雜計算器


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM