【问题标题】:How to find all the permutations of a variable amount of 0's and 1's recursively (without using itertools or random)?如何递归地找到可变数量的 0 和 1 的所有排列(不使用 itertools 或随机)?
【发布时间】:2021-02-22 17:02:21
【问题描述】:

我正在尝试为可变数量的位置生成一定数量的数字(例如,0 和 1)的所有排列。我将调用数字的数量ord(例如,ord=2 仅用于 0 和 1;ord=3 用于 0、1 和 2)和位置数量Num。因此排列的数量是ord**Num

注意:我不想使用 itertools 或任何其他类型的内置函数。我是出于好奇而提出这个问题,而不仅仅是试图找到解决方案。

对于ord=2Num=3,按任意顺序的输出应该是:

[[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]

这可以通过以下方式完成:

ord = 2 
mylist = []

for a in range(ord):
    for b in range(ord):
        for c in range(ord):
            mylist.append([a,b,c])

对于ord = 2Num = 4,输出应为:

[[0,0,0,0],[0,0,0,1],[0,0,1,0],[0,0,1,1],[0,1,0,0],[0,1,0,1],[0,1,1,0],[0,1,1,1],[1,0,0,0],[1,0,0,1],[1,0,1,0],[1,0,1,1],[1,1,0,0],[1,1,0,1],[1,1,1,0],[1,1,1,1]]

但是我必须添加另一个嵌套的 for 循环:

ord = 2 
mylist = []

for a in range(ord):
    for b in range(ord):
        for c in range(ord):
            for d in range(ord):
                mylist.append([a,b,c,d])

一个明显的解决方案是将 0 和 1 随机添加到长度为 Num 的列表中,然后如果该列表尚未添加到 mylist 中,则接受该列表,但我想要一个不完全的解决方案太可笑了。

这是迄今为止我最接近真正解决方案的方法:

def myperms(elem, mylist):
    for i in range(len(elem)-1,-1,-1):
        while (elem[i] + 1) < ord:
            elem = list(elem)
            elem[i] += 1
            if elem not in mylist:
                mylist.append(elem)
        if (elem[i] + 1) >= ord: 
            elem = list(elem)
            elem[i] = 0
    return mylist

Num = 3
ord = 2

TotsNum = ord**Num

mylist = []
elem = [0,]*Num
mylist.append(elem)

print(myperms(elem, mylist))

但这只会给出:

[[0, 0, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0]]

我已尝试在其内部调用函数(递归),但我无法弄清楚如何正确执行此操作。有没有人对如何递归解决它有任何想法?谢谢!

【问题讨论】:

    标签: python recursion permutation


    【解决方案1】:

    让我们使用递归解决方案:

    def get_seq(ord, num):
        val = [0]*num
        N = num
        def recurse(ord, num):
            for i in range(ord):
                val[N - num] = i
                if num > 1:
                    yield from recurse(ord, num-1)
                else:
                    yield val[:]
        return recurse(ord, num)
    
    print(list(get_seq(2, 4)))
    

    输出:

    [[0, 0, 0, 0],
     [0, 0, 0, 1],
     [0, 0, 1, 0],
     [0, 0, 1, 1],
     [0, 1, 0, 0],
     [0, 1, 0, 1],
     [0, 1, 1, 0],
     [0, 1, 1, 1],
     [1, 0, 0, 0],
     [1, 0, 0, 1],
     [1, 0, 1, 0],
     [1, 0, 1, 1],
     [1, 1, 0, 0],
     [1, 1, 0, 1],
     [1, 1, 1, 0],
     [1, 1, 1, 1]]
    

    对于其他输入:

    >>> list(get_seq(3, 2))
    [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
    

    【讨论】:

    • 谢谢;我无法理解代码。举个简单的例子,假设ord = 2num = 3。我看到函数recurse 将如何产生[0,0,0][0,0,1],但之后我看不到该函数如何继续循环返回以获取[0,1,0],因为一旦我们点击num = 1,@ 987654331@又涨了?也许我的困惑是由于使用yield...
    • 是的,也不是。 num 不会增加,它只是回到调用者状态。例如,如果它从n==2 开始,在产生0 之后它是yields from recurse(n==1),当recurse(n==1) 产生0 and 1 时,它会回到调用者状态,其中n2 .然后它通过产生1 结束循环
    【解决方案2】:

    使用二进制,由 0 和 1 组成。

    n = 4
    all_permutations = []
    for i in range(2**n):
        permutation = []
        string = bin(i)
        string = string.split("0b")[1]
        while len(string) != n:
            string = f"0{string}"
        
        for i in string:
            permutation.append(int(i))
    
        all_permutations.append(permutation)
    
    print(all_permutations)
    

    【讨论】:

      猜你喜欢
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 2019-04-21
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 2016-10-15
      • 2014-03-02
      相关资源
      最近更新 更多