数据结构:出栈序列

本文介绍了如何确定栈的出栈序列。通过实现两个类`Selection`和`Solution`,利用全排列算法生成所有可能的元素顺序,并结合栈的特性检查这些顺序是否符合出栈规则。代码示例展示了从给定的插入序列中找出所有可能的合法出栈序列,包括空序列、单元素序列以及多元素序列。测试用例验证了算法的正确性。

数据结构作业

Runestone Problem 01: Stack

  1. 出栈序列题目

假设元素插入的顺序是<a,b,c,d>,插入和删除操作可任意进行(例如,插入一次删除一次、插入2次删除1次、插入3次删除2次……),最后全部元素被删除。请输出所有可能的出栈序列。
例如:
输入:lst=[‘a’, ‘b’, ‘c’]
输出:return [(‘a’, ‘b’, ‘c’), (‘a’, ‘c’, ‘b’), (‘b’, ‘a’, ‘c’), (‘b’, ‘c’, ‘a’), (‘c’, ‘b’, ‘a’)]
输入:lst=[]
输出:return [()]

2.代码部分

# 判断popV是否是pushV的出栈序列
class Selection:
    def IsPopOrder(pushV, popV):
        if not pushV or len(pushV) != len(popV):
            return False
        stack = []
        index = 0
        for item in pushV:
            stack.append(item)
            while stack and stack[-1] == popV[index]:
                stack.pop()
                index += 1

        if not stack:
            return True
        else:
            return False

# 输入列表,获取列表内元素的全排序
class Solution:
    def permutation(self, s):
        if len(s) <= 1:
            return s
        str_list = []
        for i in range(len(s)):
            for j in self.permutation(s[0:i] + s[i + 1:]):
                str_list.append((s[i] + j))
        return str_list

def enum_stack_out_seq(list1: list):
    list2 = []
    if list1 == []:
        return []
    for i in list1:
        # 通过栈的pop来判断是否是可能的出栈序列
        if Selection.IsPopOrder(lst,i):
            list2.append(i)
    return list2

if __name__ == '__main__':

    # 输入测试的列表
    lst = eval(input("输入:"))
    # 将列表内元素的全排列重新组成列表
    list1=Solution().permutation(lst)
    # 列表内列表转为元组
    for x in range(len(list1)):
        list1[x] = tuple(list1[x])

    # 剔除不可能是出栈序列的元组
    list2 = enum_stack_out_seq(list1)
    print(list2)
from pythonds3.basic import Stack
from copy import deepcopy

class Selection:
    def IsPopOrder(pushV, popV):
        if not pushV or len(pushV) != len(popV):
            return False
        stack = []
        index = 0
        for item in pushV:
            stack.append(item)
            while stack and stack[-1] == popV[index]:
                stack.pop()
                index += 1

        if not stack:
            return True
        else:
            return False

# 输入列表,获取列表内元素的全排序
class Solution:
    def permutation(self, s):
        if len(s) <= 1:
            return s
        str_list = []
        for i in range(len(s)):
            for j in self.permutation(s[0:i] + s[i + 1:]):
                str_list.append((s[i] + j))
        return str_list

def stack(list1: list,lst):
    list2 = []
    if list1 == []:
        return []
    for i in list1:
        # 通过栈的pop来判断是否是可能的出栈序列
        if Selection.IsPopOrder(lst,i):
            list2.append(i)
    return list2

def enum_stack_out_seq(lst:list):

    for x in range(len(lst)):
        lst[x] = str(lst[x])
    # 将列表内元素的全排列重新组成列表
    list1=Solution().permutation(lst)
    

    # 剔除不可能是出栈序列的元组
    list2 = stack(list1,lst)
    list3 = []
    for y in range(len(list2)):
        list0 = []
        for z in range(len(list2[0])):
            list0.append(int(list2[y][z]))
        list3.append(list0)
        
    # 列表内列表转为元组
    for x in range(len(list3)):
        list3[x] = tuple(list3[x])

    return list3
    

3.测试示例

输入输出
[ ][()]
[‘a’,‘b’][(‘a’, ‘b’), (‘b’, ‘a’)]
[‘a’,‘b’,‘c’][(‘a’, ‘b’, ‘c’), (‘a’, ‘c’, ‘b’), (‘b’, ‘a’, ‘c’), (‘b’, ‘c’, ‘a’), (‘c’, ‘b’, ‘a’)]
[‘a’,‘b’,‘c’,‘d’][(‘a’, ‘b’, ‘c’, ‘d’), (‘a’, ‘b’, ‘d’, ‘c’), (‘a’, ‘c’, ‘b’, ‘d’), (‘a’, ‘c’, ‘d’, ‘b’), (‘a’, ‘d’, ‘c’, ‘b’), (‘b’, ‘a’, ‘c’, ‘d’), (‘b’, ‘a’, ‘d’, ‘c’), (‘b’, ‘c’, ‘a’, ‘d’), (‘b’, ‘c’, ‘d’, ‘a’), (‘b’, ‘d’, ‘c’, ‘a’), (‘c’, ‘b’, ‘a’, ‘d’), (‘c’, ‘b’, ‘d’, ‘a’), (‘c’, ‘d’, ‘b’, ‘a’), (‘d’, ‘c’, ‘b’, ‘a’)]
输入输出
[ ][()]
[0][(0,)]
[0,1,2][(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 1, 0)]
[0,1,2,3][(0, 1, 2, 3), (0, 1, 3, 2), (0, 2, 1, 3), (0, 2, 3, 1), (0, 3, 2, 1), (1, 0, 2, 3), (1, 0, 3, 2), (1, 2, 0, 3), (1, 2, 3, 0), (1, 3, 2, 0), (2, 1, 0, 3), (2, 1, 3, 0), (2, 3, 1, 0), (3, 2, 1, 0)]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值