所以如果我有數字[1,2,2,3],我想要k = 2分區,我會[1] [2,2,3],[1,2] [2,3], [2,2] [1,3],[2] [1,2,3],[3] [1,2,2]等我有一個數字列表,如何生成所有獨特的K分區?
回答
在Code Review參見在Python一個答案。
user3569的在Code Review溶液產生的,而不是排他地3元組5個2元組爲下面的試驗情況下,。但是,除去返回元組的frozenset()
調用將導致代碼僅返回3元組。修改後的代碼如下:
from itertools import chain, combinations
def subsets(arr):
""" Note this only returns non empty subsets of arr"""
return chain(*[combinations(arr,i + 1) for i,a in enumerate(arr)])
def k_subset(arr, k):
s_arr = sorted(arr)
return set([i for i in combinations(subsets(arr),k)
if sorted(chain(*i)) == s_arr])
s = k_subset([2,2,2,2,3,3,5],3)
for ss in sorted(s):
print(len(ss)," - ",ss)
正如user3569所說:「它運行速度很慢,但相當簡潔」。
(編輯:見下文Knuth的溶液)
的輸出是:
3 - ((2,), (2,), (2, 2, 3, 3, 5))
3 - ((2,), (2, 2), (2, 3, 3, 5))
3 - ((2,), (2, 2, 2), (3, 3, 5))
3 - ((2,), (2, 2, 3), (2, 3, 5))
3 - ((2,), (2, 2, 5), (2, 3, 3))
3 - ((2,), (2, 3), (2, 2, 3, 5))
3 - ((2,), (2, 3, 3), (2, 2, 5))
3 - ((2,), (2, 3, 5), (2, 2, 3))
3 - ((2,), (2, 5), (2, 2, 3, 3))
3 - ((2,), (3,), (2, 2, 2, 3, 5))
3 - ((2,), (3, 3), (2, 2, 2, 5))
3 - ((2,), (3, 5), (2, 2, 2, 3))
3 - ((2,), (5,), (2, 2, 2, 3, 3))
3 - ((2, 2), (2, 2), (3, 3, 5))
3 - ((2, 2), (2, 3), (2, 3, 5))
3 - ((2, 2), (2, 5), (2, 3, 3))
3 - ((2, 2), (3, 3), (2, 2, 5))
3 - ((2, 2), (3, 5), (2, 2, 3))
3 - ((2, 3), (2, 2), (2, 3, 5))
3 - ((2, 3), (2, 3), (2, 2, 5))
3 - ((2, 3), (2, 5), (2, 2, 3))
3 - ((2, 3), (3, 5), (2, 2, 2))
3 - ((2, 5), (2, 2), (2, 3, 3))
3 - ((2, 5), (2, 3), (2, 2, 3))
3 - ((2, 5), (3, 3), (2, 2, 2))
3 - ((3,), (2, 2), (2, 2, 3, 5))
3 - ((3,), (2, 2, 2), (2, 3, 5))
3 - ((3,), (2, 2, 3), (2, 2, 5))
3 - ((3,), (2, 2, 5), (2, 2, 3))
3 - ((3,), (2, 3), (2, 2, 2, 5))
3 - ((3,), (2, 3, 5), (2, 2, 2))
3 - ((3,), (2, 5), (2, 2, 2, 3))
3 - ((3,), (3,), (2, 2, 2, 2, 5))
3 - ((3,), (3, 5), (2, 2, 2, 2))
3 - ((3,), (5,), (2, 2, 2, 2, 3))
3 - ((5,), (2, 2), (2, 2, 3, 3))
3 - ((5,), (2, 2, 2), (2, 3, 3))
3 - ((5,), (2, 2, 3), (2, 2, 3))
3 - ((5,), (2, 3), (2, 2, 2, 3))
3 - ((5,), (2, 3, 3), (2, 2, 2))
3 - ((5,), (3, 3), (2, 2, 2, 2))
Knuth的溶液,如通過阿迪爾扎法爾蘇姆羅同一Code Review頁上實現可稱爲如果沒有重複如下期望:
s = algorithm_u([2,2,2,2,3,3,5],3)
ss = set(tuple(sorted(tuple(tuple(y) for y in x) for x in s)))
我沒有超時,但Knuth的解決方案是明顯更快,即使是在這個測試案例。
但是,它返回63個元組,而不是由user3569的解決方案返回的41個元組。我還沒有經過足夠的輸出來確定哪個輸出是正確的。
這仍然具有嚴重的內存和速度限制 – KaliMa 2013-03-10 02:24:09
鑑於我們在尋找能夠產生正確輸出的解決方案方面存在困難,儘管其內存和速度有限制,但該解決方案至少可以作爲運行解決方案的自動化測試的基礎更快,並使用更少的內存。我非常贊成首先讓代碼正常工作,然後考慮速度。我認爲下一步可能是爲了適應Knuth的解決方案來滿足這個問題的規範,因爲如果我們能夠解決這個問題,Knuth的解決方案會更快。 – Simon 2013-03-10 02:34:20
有沒有辦法修改Knuth算法來避免創建那麼多重複? – KaliMa 2013-03-10 03:51:22
下面是Haskell的一個版本:
import Data.List (nub, sort, permutations)
parts 0 = []
parts n = nub $ map sort $ [n] : [x:xs | x <- [1..n`div`2], xs <- parts(n - x)]
partition [] ys result = sort $ map sort result
partition (x:xs) ys result =
partition xs (drop x ys) (result ++ [take x ys])
partitions xs k =
let variations = filter (\x -> length x == k) $ parts (length xs)
in nub $ concat $ map (\x -> mapVariation x (nub $ permutations xs)) variations
where mapVariation variation = map (\x -> partition variation x [])
OUTPUT:
*Main> partitions [1,2,2,3] 2
[[[1],[2,2,3]],[[1,2,3],[2]],[[1,2,2],[3]],[[1,2],[2,3]],[[1,3],[2,2]]]
Python的解決方案:
pip install PartitionSets
然後:
import partitionsets.partition
filter(lambda x: len(x) == k, partitionsets.partition.Partition(arr))
的PartitionSets實施似乎是相當快速但它是一個遺憾,你可以不會將分區數量作爲參數傳遞,因此您需要從所有子集p中篩選您的k-集分區artitions。
您可能還需要查看: similar topic on researchgate。
- 1. 生成一個整數的所有組成k部分
- 2. 生成所有獨特的排列
- 3. 生成所有獨特的井字板的列表
- 4. 生成所有具有所有唯一k位子序列的n位序列。
- 5. 如何從k個項目列表中生成所有n大小的集合?
- 6. 生成一個數字的分區
- 7. 生成一個集合的所有相同大小的分區
- 8. 選擇所有列並按一個特定列區分
- 9. 生成一組(而不是冪)的所有「獨特的」子集
- 10. 從數字列表生成所有唯一對,n選擇2
- 11. 我如何做一個隨機生成一個特定區域
- 12. 我如何生成一系列數字?
- 13. 列出k個數字的所有排列,取自0:k,表示總和爲k
- 14. 生成k個最獨特的子集對元素
- 15. 如何從關鍵字列表中生成所有組合?
- 16. 找到1之間的n個數的所有獨特combenations和k
- 17. 生成所有列表(排列)
- 18. 我有3個表如何加入他們生成一個表?
- 19. TestNG DataProvider - 如何生成列表中的所有排列
- 20. 如何生成獨特的字母數字?
- 21. Make:如何生成除一個以外的所有.c文件的列表
- 22. 如何擁有一個獨特的學生編號
- 23. 以字典順序生成列表的所有排列
- 24. 調度:分區是一個整數集成K個子集
- 25. 如何按字典順序生成由`k`` 0``和`l``1``組成的集合的所有排列?
- 26. 如何在Perl中生成長度爲k的所有有序組合?
- 27. 在SQL中,如何生成5!56的所有可能的獨特組合?
- 28. 如何將文本列分成包含所有行的列表?
- 29. 如何從我在Sqlite中選擇的所有列中區分出一列
- 30. Oracle 12c - 如何查看某個表的所有分區和子分區以及每個分區的記錄數
此代碼生成重複,只需要連續子集 – KaliMa 2013-03-10 00:56:06
丟失重複,您可以執行類似操作:set(results) – eyaler 2013-03-10 00:57:53
您是否看過Adeel Zafar Soomro的第一個答案中的代碼? – eyaler 2013-03-10 01:00:43