所以如果我有数字[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路分区递归算法
- 5. 生成所有具有所有唯一k位子序列的n位序列。
- 6. 分区一套成恰好有k块
- 7. 如何生成种子串的所有独特的4字符排列?
- 8. 如何从k个项目列表中生成所有n大小的集合?
- 9. 生成一个数字的分区
- 10. 生成一个集合的所有相同大小的分区
- 11. 生成一组(而不是幂)的所有“独特的”子集
- 12. 选择所有列并按一个特定列区分
- 13. 生成k个成对独立散列函数
- 14. 生成相同数字的两个数字的所有排列
- 15. 在R中生成k个序数的所有二叉树R
- 16. 从数字列表生成所有唯一对,n选择2
- 17. 生成一些数字范围的所有排列序列
- 18. 我如何做一个随机生成一个特定区域
- 19. Python生成带有独特词法元素的列表
- 20. 我如何生成一系列数字?
- 21. 如何生成单词列表的所有唯一组合?
- 22. 如何生成几个字母的所有可能排列列表?
- 23. 列出k个数字的所有排列,取自0:k,表示总和为k
- 24. 如何从列表中获取所有独特的posiblity?
- 25. 生成k个最独特的子集对元素
- 26. 如何从关键字列表中生成所有组合?
- 27. 的Python:将一个字符串分解成一个列表,取出所有的特殊字符,除了“
- 28. 找到1之间的n个数的所有独特combenations和k
- 29. Haskell列表的所有可能分区
- 30. 生成所有列表(排列)
此代码生成重复,只需要连续子集 – 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