递归-如何生成具有给定n和k

时间:2018-11-24 21:00:12

标签: algorithm recursion combinatorics

鉴于n和k,我需要生成以下所有序列:

n=5, k=2
0,1,2
0,1,3
0,1,4
1,2,3
1,2,4
2,3,4

另一个例子:

n=5, k=3
0,1,2,3
0,1,2,4
0,1,3,4
0,2,3,4
1,2,3,4

我认为可以使用递归解决此问题,但遇到了麻烦。需要帮助

1 个答案:

答案 0 :(得分:0)

似乎您已经知道如何生成序列,因此只需描述一下头脑中使用的规则即可。然后从那里向后处理程序。

  1. 每个组合c将成为一个列表; [0,1,2][0,1,3]等。我们将空组合初始化为c = [],即空列表。循环时,“选择的”值将添加到我们的组合中。

  2. 我们想选择k个值。一旦k小于零,我们就不能再向我们的组合c添加任何值。输出组合。

  3. 选择的值将从0开始,一直计数到n。我们将用m表示当前值,并用我们的起始值m = 0对其进行初始化。一旦m等于n

  4. ,就停止生成值
  5. 通过选择m开始。做出选择意味着将k减少1。做出选择还意味着将其添加到我们与c + [m]的组合中。下一个选择是m + 1

  6. 接下来,我们选择m。不作出选择意味着k还原。我们的组合c保持不变。移至下一个值m + 1

该代码现在大部分会自行编写

def combnk (n, k, m = 0, c = []):                 # 1
  if k < 0:
    yield c                                       # 2
  elif n == m:
    return                                        # 3
  else:
    yield from combnk (n, k - 1, m + 1, c + [m])  # 4
    yield from combnk (n, k    , m + 1, c      )  # 5

print (list (combnk (5, 2)))
# [ [0, 1, 2]
# , [0, 1, 3]
# , [0, 1, 4]
# , [0, 2, 3]
# , [0, 2, 4]
# , [0, 3, 4]
# , [1, 2, 3]
# , [1, 2, 4]
# , [1, 3, 4]
# , [2, 3, 4]
# ]

print (list (combnk (5, 3)))
# [ [0, 1, 2, 3]
# , [0, 1, 2, 4]
# , [0, 1, 3, 4]
# , [0, 2, 3, 4]
# , [1, 2, 3, 4]
# ]