• 列表元素的所有排列


    列表元素的所有排列

      case:有乱序、不定长列表如[1,3,5,2],打印所有列表元素所有排列情况,并计数

     

      思路:重复的步骤--》长度为n的排列-》长为n-1的排列,长为n-2的排列

      .........

      直到长度为1,只有一个元素,输入当前的排列顺序

    n = [1,2,3,4]
    res = []
    count = 0
    
    def func1(k,start,end):
        global count
        if end == start:
            count += 1
            print(k)
            # res.append(k[:])
            return
        for i in range(start,end+1): #循环列表,从列表中选取一个元素作为排列的首元素,将剩余n-1的序列传入子递归函数
            k[start],k[i] = k[i],k[start] 
            
            func1(k,start+1,end)
            k[start],k[i] = k[i],k[start] # 将替换后的序列重置为原来的序列,确保后续循环中,选出的首元素是没选择过的元素
      # 递归层数从上往下(由外到内)的过程中对列表进行新的排列,
      # 由内到外的过程中将列表重置为每层递归函数传入列表的时的排序方式
    func1(n,0,len(n)
    -1) print(count)

      升级:将所有排列结果放在一个大列表中

    n = [1,2,3,4]
    res = []
    count = 0
    
    def func1(k,start,end):
        global count
        if end == start:
            count += 1
            print(k)
            res.append(k[:])
            return
        for i in range(start,end+1):
            k[start],k[i] = k[i],k[start]
            
            func1(k,start+1,end)
            k[start],k[i] = k[i],k[start]
    
    func1(n,0,len(n)-1)
    print(count)

      解释:为什么res.append(k[:])而不是res.append(k)?

      所有递归层数中操作的同一个对象(对象的不同引用),

      res.append(k)以后,最终的列表中子元素列表k都指向同一个对象

      第一句k[start],k[i] = k[i],k[start] 对列表k重新排序之后

      第二句k[start],k[i] = k[i],k[start] 将列表重置为原来的排序方式,最终结果res大列表中,所有子元素列表都指向同一个对象(新排序然后又重置为原来排序方式的列表)

      所以要用切片(浅copy)copy出值相同对象(值相等,但是是两个列表对象)

      深浅copy(对象与引用)请参照我的另一篇文章

      https://www.cnblogs.com/rain-chenwei/p/10222990.html

    
    

     

  • 相关阅读:
    《Effective Java》第9章 异常
    《Effective Java》第7章 方法
    《Effective Java》第6章 枚举和注解
    《Effective Java》第5章 泛型
    《Effective Java》第4章 类和接口
    《Effective Java》第3章 对于所有对象都通用的方法
    使用Spring加载properties配置文件.md
    第7章 插件的使用和写法
    第6章 jQuery与Ajax的应用
    第5章 jQuery对表单、表格的操作及更多应用
  • 原文地址:https://www.cnblogs.com/rain-chenwei/p/10223099.html
Copyright © 2020-2023  润新知