通过全排列以及判断的方法来求出所有的出栈序列(Python)

本文介绍了如何设计函数生成给定元素的全排列,并通过函数2判断出栈序列是否合法。通过实例展示了如何利用这两个函数解决特定的出栈序列查找问题。
摘要由CSDN通过智能技术生成

        算法思路:

        设计一个函数1,可以根据给定的元素,将元素进行全排列,从而获取出栈序列(不过注意:这个出栈序列不一定是合法的)

        (函数1的具体实现方法与讲解:列出n个元素的全排列结果

        再设计一个函数2,给定一个出栈序列和一个入栈序列,就可以判断给定的出栈序列是否合法。

        (函数2的具体实现方法与讲解:判断出栈序列的正误

        用户输入入栈的序列,使用函数1得到一个含有全排列的列表,再使用函数2进行循环来判断由函数1获取的出栈序列,并将其中符合条件的出栈序列进行输出。

        

"""通过解决“列出一组入栈元素的全排列”与“判断指定出栈序列是否存在”这个两个问题来解决“如何找出给定的一串入栈序列所对应的所有出栈序列”"""
import copy
#子函数:用来确定某元素对应在入栈序列中的编号
def find_number(stack_in_sequence,element):
    for i in range(len(stack_in_sequence)):
        if stack_in_sequence[i]==element:
            return i
    return -1
#函数1:用来生成全排列的
def Permutations(elements):
#建立一个列表1和列表2用来存储排列情况 
    permutation_1=[]
    permutation_2=[]
    a_permutation=[]
    permutation_1=[[elements[0]]]#列出(排列第一个元素)的排列
#按照预设的算法执行
    for i in range(1,len(elements)):#(循环)选定待放置(插入)的元素
        if (i+1)%2==0:#判断是用列表1还是列表2来储存即将生成的新排列
            for j in range(0,len(permutation_1)):#(循环)选定之前排列好的排列
                for k in range(0,i+1):#(循环)开始在每一个排列里可以插入元素的位置上插入元素
                    a_permutation=copy.deepcopy(permutation_1[j])
                    a_permutation.insert(k,elements[i])
                    permutation_2.append(a_permutation)     
            for m in range(0,len(permutation_1)):#清空列表1
                del permutation_1[0]
        else:
            for j in range(0,len(permutation_2)):#(循环)选定之前排列好的排列
                for k in range(0,i+1):#(循环)开始在每一个排列里可以插入元素的位置上插入元素
                    a_permutation=copy.deepcopy(permutation_2[j])
                    a_permutation.insert(k,elements[i])
                    permutation_1.append(a_permutation)       
            for m in range(0,len(permutation_2)):#清空列表2
                del permutation_2[0]
    if len(elements)%2==1:#判断是用列表1还是列表2来输出获取的全排列
        return permutation_1
    else:
        return permutation_2
#函数2:用来判断给定的某出栈序列是否是正确的
def judge(stack_in_sequence,stack_out_sequence):
    stack_out_number_sequence=[]
    for j in range(0,len(stack_out_sequence)):
         if find_number(stack_in_sequence,stack_out_sequence[j])==-1:
             print('The sequence is wrong!')
             exit(0)
         stack_out_number_sequence.append(find_number(stack_in_sequence,stack_out_sequence[j]))
#从指定序列的第1个元素开始做循环判断到第i-1个元素(即可)//Start a loop to judge from the first element of the specified sequence up to the (i-1)th element.
    p=0#用来判断(以单个元素为起点开始做循环时)是否出现可以否定此序列的判定点,p==0时无,p==1时是
    for k in range(0,len(stack_out_sequence)):
     m=stack_out_number_sequence[k]
     for l in range(k+1,len(stack_out_sequence)):#判断在第l个元素之后小于此元素的元素是否相对于入栈顺序互逆,若是i++,若否跳出循环,判定为非出栈序列
                           #//Check if the elements smaller than the ith element, after it, are in the reverse order compared to the stack pushing order.
                           #If yes, increment i. If no, exit the loop and judge it as a non-stack popping sequence.
        if stack_out_number_sequence[l]<stack_out_number_sequence[k]:
            if stack_out_number_sequence[l]<m:
                m=stack_out_number_sequence[l]
            else:
                p=1
                break
     if p==1:
        return False
     else:
         if k==len(stack_out_sequence)-1:#若k==len(stack_out_sequence)-1,则此出栈序列存在//If the marker variable n equals to i-1, then this stack popping sequence exists.
             return True   
#输入入栈序列(有i个元素)//Input the stack pushing sequence (with i elements)
print('Please enter the stack sequence and use "over" as the identifier to end the input:')
stack_in_sequence=[]
i=0#用i来标记栈中有多少个元素//How many elements are in the stack
while(1):
    a=input()
    if a=="over":
        break
    else:
        stack_in_sequence.append(a)
        i+=1
for i in range(0,len(Permutations(stack_in_sequence))):
    if judge(stack_in_sequence,Permutations(stack_in_sequence)[i])==True:
        print(Permutations(stack_in_sequence)[i])
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值