zoukankan      html  css  js  c++  java
  • 一道小题加深对栈后进先出的理解(python)

    今天有人问了我一道题,如下:
    在这里插入图片描述
    意思就是给定一个顺序为654321的栈,判断下面的栈是否是正确的。

    解题思路

    栈的元素存储与利用是遵循后进先出(LIFO)的,如下图,我们可以用一个半开口的方框表示栈,开口的一端称为栈顶,就是这端进行着压栈(push)和出栈(pop)操作。
    在这里插入图片描述
    对于给定的待判断序列,比如这里的A选项453126,我们可以依次按照这个序列的顺序进行推演,

    • 首先是第一个元素4,我们可以用这个元素"4"将原栈一分为二,即第一步,左边为原栈wt,右边为st_tmp,注意st_tmp开口方向相反。
    • 然后我们先判断st的栈顶是否是当前遍历的元素"4",如果是就pop掉,并遍历下一个元素"5",如第二步,
    • 按照相同操作我们来到第三步。此时遍历到元素"3",此时左边st的栈顶并不等于元素"3",因此我们需要从st_tmp中依次从栈顶找到并push到左边的st然后再pop掉,这一步可以简化为直接pop掉。
    • 到了第四步遍历"1"时,我们发现左边st的栈顶也没有,右边st_tmp的栈顶也没有,此时我们就要逐次把st_tmp的栈顶push到左边,直到发现st_tmp的栈顶等于此时遍历的元素"1"为止。如果此时不幸pop掉了st_tmp中的所有元素也没有找到元素"1",说明该序列并不是正确的序列
    • 幸运的是这里还是找到了元素"1"并pop掉,如第六步
    • 接下来的步骤都是类似的操作,如果最后成功pop掉st和st_tmp中的所有元素,说明该序列是正确的,即原栈654321可以通过一系列的push/pop步骤得到该序列。

    代码实现

    代码实现如下,这里不仅能实现654321的判断,还能实现其他个数比如4321的判断,只需要更改变量n即可,不仅仅是个数,对于任意栈如343453等同样适用,只需要更改栈的初始化即可。

    class StackUnderflow(ValueError):
        '''自定义栈相关的异常类
        '''
        pass
    
    class SStack:
        '''基于顺序表实现的栈类
        '''
    
        def __init__(self):
            self._elems = []  # 用list对象 _elems存储栈中元素
    
        def is_empty(self):
            return self._elems == []
    
        def top(self):  # 取得最后压入的元素,即栈顶
            if self._elems == []:
                raise StackUnderflow("in SStack.pop()")
            else:
                return self._elems[-1]
    
        def push(self, elem):  # 压栈
            self._elems.append(elem)
    
        def pop(self):  # 出栈
            if self._elems == []:
                raise StackUnderflow("in SStack.pop()")
            return self._elems.pop()
    
        def elems(self):
            elems = self._elems
            return elems
    
    
    st = SStack()
    flag = True
    # n = int(input("栈元素个数:"))
    n = 6 # n也可以改为其他的
    for i in range(n, 0, -1):
        st.push(i)
    st_tmp = SStack()
    input_series = input("输入待判断序列")
    series_list = list(map(int, input_series))
    print(series_list)
    
    while not st.top() == series_list[0]:  # 以待判断序列首元素为界,将原栈一分为二
        st_tmp.push(st.top())
        st.pop()
    
    for serie in series_list:
        if (not st.is_empty()) and serie == st.top():
            st.pop()
        else:
            if st_tmp.is_empty():
                flag = False
            else:
                while not serie == st_tmp.top():
                    st.push(st_tmp.top())
                    st_tmp.pop()
                    if st_tmp.is_empty():
                        break
                if st_tmp.is_empty():
                    flag = False
                else:
                    st_tmp.pop()
        if flag == False:
            break
    
    print(flag)
    

    后记

    如果觉得本文有帮助,欢迎点赞+收藏以提供博主源源不断的更文动力。另外欢迎关注个人公众号,二维码如下:
    Alt

  • 相关阅读:
    sqlmap注入教程
    Burp Suite使用详解一
    手工注入基本思路
    搜索型注入漏洞手工注入过程
    龙灵:特邀国内第一讲师“玄魂” 在线培训黑客神器Kali Linux
    linux grep命令详解
    linux ps命令详解
    linux DNS服务
    linux用户与组管理命令的基本操作
    canvas绘制坐标轴
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13281680.html
Copyright © 2011-2022 走看看