python实现栈以及栈在中后缀表达式中的应用

笔者是python初学者,如有不妥,请各位指教,多谢大家。写博客不仅仅是为了记录自己的学习过程,还想向大家学习高超的cs技术。


栈的特点很简单  ---->  后进先出,实现过程中,只要遵守该特点即可,其他都是语言特性。

笔者用一个python定义栈的节点,节点(node)包括 元素(elem)和下一个元素(next)

class Node(object):
    def __init__(self , elem):
        self.elem = elem
        self.next = None

栈(Stack)的本身,笔者用了也用了一个类进行表示,其属性包括:栈的大小(size)、栈顶位置(top)、存储栈元素的结构(stack)

import random
class Stack(object):
    def __init__(self , size = 0):
        self.size = size # 堆栈的大小
        self.stack = [] # 列表表示栈
        self.top = -1 # 栈顶位置
    
    def empty(self):
        return self.top == -1 
    
    def full(self):
        return self.top + 1 >= self.size
    
    def length(self):
        return self.size
    
    def getElementCount(self):
        return self.top + 1
    
    def getTop(self):
        if self.empty() is False:
            return self.stack[self.top]
    
    def pop(self):
        if self.empty() is True:
            print("maybe this stack is empty,pop error , please check the stack you init")
            return 
        temp_mum = self.stack.pop()
        print("pop the element is ->",temp_num) # 这行代码是打印的代码,在下面的应用中已经进行了注释
        self.top -= 1
    
    def push_many(self,num):
        if isinstance(num,list) is False:
            print("premeters is error , please check yourself")
            return
        if len(num) + self.top + 1 > self.size: # 如果这个列表元素的总数加上现在的数目大于栈的大小,则该列表不能插入栈中
            print("this list is too long")
            return
        for i in num:
            self.push(i)
        print("push_many is right") # 这行代码是打印的代码,在下面的应用中已经进行了注释
        
    
    def push(self,elem):
        if self.full() is True:
            print("maybe this stack is full,push ",elem," error ,please check the stack you init")
            return 
        self.top = self.top + 1
        print(self.top ,"\t" ,self.size,"\t",elem) # 这行代码是打印的代码,在下面的应用中已经进行了注释
        self.stack.append(elem)
    
    def show(self):
        if self.empty() is True:
            print("maybe this stack is empty,show error , please check the stack you init")
            return
        i = self.top
        while i >= 0:
            print(self.stack[i])
            i -= 1

测试代码如下:

if __name__ == "__main__":
    stack_temp = Stack(12)
    stack_temp.push(12)
    print(stack_temp.empty())
    stack_temp.pop()
    print(stack_temp.length() ,"<----->",stack_temp.getElementCount())
    stack_temp.show()
    print("positon\t","size\t","push_element")
    for i in range(12):
        temp = random.randint(12 , 220)
        stack_temp.push(temp)

    print("===============show the stack================")
    stack_temp.show()

 

运行结果:


栈在中后缀表达式中的应用

中缀表达式转换为后缀表达式的步骤如下:

  1. 给出待处理的字符串,对给出的字符串进行预处理,进而形成相应的列表
  2. 遍历整个列表,判断当前元素是否为运算符,如果是运算符,则进行第3步,否则跳入第6步
  3. 判断运算符栈是否为空,如果为空,则将当前的运算符压入栈中,否则进行第4步
  4. 判断当前字符是否是 ‘)‘,如果是的话,则将运算符栈中的栈顶元素压入结果列表中,直到碰见与之对应的’(’结束,跳到第2步,进行下一轮遍历。
  5. 算出当前字符的优先级x_elem 和运算符栈栈顶元素的优先级x_top,如果x_top 小于x_elem,则将当前的字符压入运算符栈中,否则,将运算符栈栈顶元素压入到结果列表中,直到x_top 小于 x_elem。然后再将当前字符压入运算符栈中。跳到第2步,进行下一轮遍历。
  6. 将当前元素加入到结果列表中,跳到第2步,进行下一轮遍历。
  7. 如果运算符栈还没有为空,则将栈中的所有元素依次压入结果列表中。完成

代码如下:

def get_core(str_temp):# 设定相应的优先级
    if str_temp == '+' or str_temp == '-':
        return 1
    elif str_temp =='*' or str_temp == '/':
        return 2
    elif str_temp == '(' or str_temp == ')':
        return 4
    else:
        print(str , " is not defined")

def judge_tool(str_temp):# 判断是否是运算符
    if str_temp in ('-','+','*','/','(',')'):
        return True
    return False 

def middle2Final(str_temp): #将中缀表达式转换成后缀表达式
    if isinstance(str_temp , str) is False: #如果参数不是字符串,则不满足程序要求,退出程序
        print("type error")
        exit()
    
    stack_tool = Stack(100) #定义运算符栈
    
    '''
    在将字符串转换成列表后,第一:会有相应的空格(这是参数自身带来的空格);第二:会把多位数分离掉,因为在将字符串转换成列表的过程中,
    它是以一个字符作为一个列表元素的方式,所以,会对多位数进行切割,例如 666 会切割成 ['6','6','6'],我们得将其再次拼接
                对数据的处理有两种
    
    1、将传过来的参数中的空格进行切除
    2、对转换来的列表进行拼接
    '''
    #===========================以下是对数据的处理=======================================
    
    list_temp = list(str_temp) # 去空格前的表达式
    
    list_operate = [] # 去空格后的表达式
    result_list = [] # 结果列表
    
    for ele in list_temp: #去掉字符中的空格
        if ele != ' ':
            list_operate.append(ele)
    
    list_t = [] # 处理好的表达式
    
    str_temp_num = '' # 暂存拼接好的数据
    
    
    for ele in list_operate:
        if judge_tool(ele) is True:
            if str_temp_num != '':#因可能会有两个相邻的运算符,所以会存在 '' 的情况,我们得过滤掉这种情况
                list_t.append(str_temp_num)
            str_temp_num = ''
            list_t.append(ele)
            continue
        str_temp_num += ele
    if str_temp_num != '':
        list_t.append(str_temp_num)
    
    #===========================以上是对数据的处理=======================================
    
    #==================以下是中缀表达式转换成后缀表达式的过程=============================
    string = "" # 用字符串记录中缀转换成后缀的结果,该变量只是为了从感性上能容易看出结果而已,没有实际意义
    flag = False
    
    for ele in list_t:
        if judge_tool(ele) is True:# 所读的字符为运算符
            if stack_tool.empty() is True:# 如果栈中没有运算符,则将当前的运算符压入栈中即可
                stack_tool.push(ele)
                continue
            if ele == ')': # 如果当前的运算符为 ) ,则将运算符栈中的所有运算符输出,遇见 (
                #print("enter here")
                while stack_tool.empty() is False:
                    top_element_temp = stack_tool.getTop()
                    if top_element_temp == '(':
                        flag = True
                        #print(top_element_temp+"======================")
                        stack_tool.pop()
                        break
                        
                    string = string + top_element_temp
                    result_list.append(top_element_temp)
                    stack_tool.pop()
                    
                #stack_tool.show()
                #print("-------------------------")
                continue
            
            x_top = get_core(stack_tool.getTop()) # 栈顶运算符的优先级
            x_elem = get_core(ele) # 当前运算符的优先级
            
            if x_top < x_elem: #如果栈顶元素的优先级小于当前元素的优先级
                stack_tool.push(ele)
            else:
                while x_elem <= get_core(stack_tool.getTop()) and stack_tool.getTop() != '(':
#                     print(stack_tool.getTop())
                    string = string + stack_tool.getTop()
                    result_list.append(stack_tool.getTop())
                    stack_tool.pop()
                    if stack_tool.empty() is True:
                        break
                stack_tool.push(ele)
                #print('=========================')
                #stack_tool.show()
                #print('=========================')
        else:
            string = string + ele
            result_list.append(ele)

    while stack_tool.empty() is False: # 如果堆栈中还有数据,则依次弹出即可
        string = string + stack_tool.getTop()
        result_list.append(stack_tool.getTop())
        stack_tool.pop()
        
    #==================以上是中缀表达式转换成后缀表达式的过程=============================
    
    #=========================以下是简单的格式检查过程====================================
    if flag is False:
        print("the statement of computation is error,expect for '('")
        return 
    
    if '(' in string: # 如果堆栈中还有(,则表示没有) 跟(进行匹配,
        print("the statement of computation is error,expect for '('")
        return
    print(string)
    return result_list

 

后缀表达式值的运算代码如下:

def calculate(expression): # 给出后缀表达时,计算出表达式的值
    if isinstance(expression,list) is False:
        print("premeters is error , please check yourself")
        return
    
    cal_stack = Stack(100)
    temp_num1 = 0
    temp_num2 = 0
    for elem in expression:
        if judge_tool(elem) is True:
            if cal_stack.empty() is True:
                print("this expression is error ,pleace check it")
                return
            temp_num1 = int(cal_stack.getTop())
            cal_stack.pop()
            
            if cal_stack.empty() is True:
                print("this expression is error ,pleace check it")
                return
            
            temp_num2 = int(cal_stack.getTop())
            cal_stack.pop()
            if elem == '*':
                cal_stack.push(temp_num2 * temp_num1)
            elif elem == '/':
                if temp_num2 == 0:
                    print("this expression is error, please check it")
                    return
                cal_stack.push(temp_num1 / temp_num2)
            elif elem == '-':
                cal_stack.push(temp_num1 - temp_num2)
            elif elem == '+':
                cal_stack.push(temp_num1 + temp_num2)
            else:
                print("have no this operation , please check it because you are maybe error")
        else:
            cal_stack.push(elem)
            
    return cal_stack.getTop()

测试代码如下:

if __name__ == "__main__":
    
    expression = middle2Final("12 + 2* (3+(4*2+3)*2)")
    print(expression)
    print(calculate(expression))
    #middle2Final("a + b + c+d-e+f*g")

运行结果如下:

注意:这几个代码式一起用的,后面所用到的栈都是前面定义的栈,后缀表达式计算需要将中缀表达式转换成后缀表达式

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值