使用递归从长度为 n 的列表中计算长度为 k 的组合
我需要从长度为 n 的列表中生成长度为 k 的所有组合,并且必须使用递归来完成。
例如:
INPUT: choose_sets([1,2,3,4],3)
OUTPUT: [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
INPUT: choose_sets([1,2,3,4],2)
OUTPUT: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
我一直在代码中实现这一点,所以我很乐意获得一些帮助。 到目前为止,这是我的代码(我错过了一些东西,只是不知道是什么):
def choose_sets(lst,k):
if k == len(lst):
return lst
if k == 0:
return []
if k > len(lst):
return []
sets=[]
sub_lst=lst[:]
sub_lst.remove(sub_lst[0])
a= choose_sets(sub_lst,k-1)
for i in a:
i.append(lst[0])
sets.append(a)
b= choose_sets(sub_lst,k)
sets.append(b)
return sets
I need to generate all the combinations with length k
from a list of length n
, and I must do it using recursion.
For Example:
INPUT: choose_sets([1,2,3,4],3)
OUTPUT: [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
INPUT: choose_sets([1,2,3,4],2)
OUTPUT: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
I'm stuck implementing this in code, so I would be happy for some help.
This is my code so far (I'm missing something just don't know what):
def choose_sets(lst,k):
if k == len(lst):
return lst
if k == 0:
return []
if k > len(lst):
return []
sets=[]
sub_lst=lst[:]
sub_lst.remove(sub_lst[0])
a= choose_sets(sub_lst,k-1)
for i in a:
i.append(lst[0])
sets.append(a)
b= choose_sets(sub_lst,k)
sets.append(b)
return sets
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以从 排列、组合、选择的生成器获得解决方案一个序列(Python 配方)
4 年后编辑 (2015 年 7 月 12 日)
要在 Python3 上运行它,只需更改
xrange
到range
,Python3 的范围是 Python2 的 xrange。。感谢 @ederollora 注意到我。You can get solution from Generator for permutations, combinations, selections of a sequence (Python recipe)
Edited 4 year later (7/12/2015)
To run it on Python3 just change
xrange
torange
, Python3's range is Python2's xrange.. Thanks @ederollora to notice me.看看这个解决方案:
还有更优雅的方法,但这应该可以作为家庭作业......
Give a look to this solution:
there are more elegant ways, but this should be ok as homework...
这是用 Java 编写的,我不能保证它 100% 正常工作,但基于快速原型设计似乎工作正常。希望这在任何情况下都能有所帮助。
This is in Java, and I can't guarantee it works 100% properly, but based on quick prototyping seemed to work ok. Hope this helps a bit in any case.
基本上你需要使用以下递归:
f(k,n) =append_to_each( f(k-1,n-1), n) | f(k,n-1)
basically you need to use the following recursion:
f(k,n) = append_to_each( f(k-1,n-1), n) | f(k,n-1)
你已经快到了,只需要一些小事情。该算法基本上是正确的,但是
This 的类型错误。返回类型不是 thing 列表,而是 (thing 列表) 列表,因此应该是
Next,
每个列表都有一个非空子列表,即空列表,所以这应该是
对于其余的,
是完全正确的。
这是正确的,但可以更简洁地表述为
现在,另一种类型混合:
sets.append(a)
将a
放入sets< 的一个槽中/code>,您想要连接两个列表,
sets = sets + a
。如果您希望按照元素在列表中出现的顺序进行组合,则应附加[lst[0]] +,而不是
到循环中的i.append(lst[0])
isets
,但这是一个倾向问题。再次强调,不要追加,而是在这里连接,
You are almost there, just a few minor things. The algorithm is basically correct, but
This has the wrong type. The return type is not a list of thing, but a list of (list of thing), so that should be
Next,
Every list has exactly one nonempty sublist, the empty list, so that ought to be
For the rest,
is completely correct.
That is correct but could be put more succinctly as
Now, another type mix-up:
That
sets.append(a)
putsa
into one slot ofsets
, you want to concatenate the two lists,sets = sets + a
. And if you would like the combinations in the order in which elements appear in the list, instead ofi.append(lst[0])
, you should append[lst[0]] + i
tosets
in the loop, but that's a matter of inclination.Again, do not append, but concatenate here,