[英]Calculating combinations of length k from a list of length n using recursion
我需要從長度為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
您可以從Generator獲取解決方案的排列,組合和選擇(Python配方)
def xuniqueCombinations(items, n):
if n==0: yield []
else:
for i in xrange(len(items)):
for cc in xuniqueCombinations(items[i+1:],n-1):
yield [items[i]]+cc
>>> def xuniqueCombinations(items, n):
... if n==0: yield []
... else:
... for i in xrange(len(items)):
... for cc in xuniqueCombinations(items[i+1:],n-1):
... yield [items[i]]+cc
...
>>> for x in xuniqueCombinations( [1,2,3,4],2):
... print x
[1, 2]
[1, 3]
[1, 4]
[2, 3]
[2, 4]
[3, 4]
4年后編輯 (2015 年12月 7日)
要在Python3上運行它只需將xrange
更改為range
, Python3的范圍是Python2的xrange。 。 謝謝@ederollora注意到我。
這是Java,我不能保證它100%正常工作,但基於快速原型設計似乎工作正常。 希望這在任何情況下都有所幫助。
public void choose_sets(int values[], int count) {
int perm[] = new int[count];
choose_sets(values, 0, perm, 0, count);
}
public void choose_sets(int[] values, int valuesIdx, int[] perm,
int permIdx, int count) {
if (permIdx == count) {
// At this point perm -array contains single permutation
// of length ´count´.
} else {
for (int i = valuesIdx; i < values.length; ++i) {
perm[permIdx] = values[i];
choose_sets(values, i + 1, perm, permIdx + 1, count);
}
}
}
看看這個解決方案:
def choose_sets(mylist,length):
mylen = len(mylist)
if length == mylen:
return [mylist]
if length == 1:
return [[i] for i in mylist]
if length > mylen:
return []
ToRet = []
for k in xrange(mylen):
if mylen - k + 1> length :
for j in choose_sets(mylist[k+1:],length-1):
New = [mylist[k]]
New.extend(j)
ToRet.append(New)
return ToRet
print choose_sets([1,2,3,4,5],3)
有更優雅的方式,但這應該是作為功課...
你幾乎就在那里,只是一些小事。 該算法基本上是正確的,但是
if k == len(lst):
return lst
這有錯誤的類型。 返回類型不是事物的列表,而是( 事物列表)的列表,所以應該是
if k == len(lst):
return [lst]
下一個,
if k == 0:
return []
每個列表都有一個非空的子列表,空列表,所以應該是
if k == 0:
return [[]]
對於其余的,
if k > len(lst):
return []
是完全正確的。
sets=[]
sub_lst=lst[:]
sub_lst.remove(sub_lst[0])
這是正確的,但可以更簡潔地說
sub_lst = lst[1:]
現在,另一種類型的混淆:
a= choose_sets(sub_lst,k-1)
for i in a:
i.append(lst[0])
sets.append(a)
這sets.append(a)
把a
成一個槽sets
,要連接兩個列表, sets = sets + a
。 如果你想按照元素出現在列表中的順序組合,而不是i.append(lst[0])
,你應該將[lst[0]] + i
追加到循環中的sets
,但那是一個傾向的問題。
b= choose_sets(sub_lst,k)
sets.append(b)
再次,不要追加,但在這里連接,
sets = sets + b
基本上你需要使用以下遞歸:
f(k,n)= append_to_each(f(k-1,n-1),n)| F(K,N-1)
def combinations(lst,k):
n = len(lst)
if n == k:
return [set(lst)]
if k == 1:
return [set([lst[i]]) for i in range(n)]
v1 = combinations(lst[:-1], k-1)
v1new = [ i.add(lst[n-1]) for i in v1]
v2 = combinations(lst[:-1], k)
return v1+v2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.