【发布时间】:2022-01-03 23:31:18
【问题描述】:
有很多关于堆栈溢出的快速方法可以生成大小为 k 的位集的所有组合。
例如:
combos(4,3) = {1110,1101,1011,0111}
但是,有没有一种快速的方法来计算尺寸 1 到 n 的所有组合?
例如:
allCombos(4) =
{
1: {0001, 0010, 0100, 1000}
2: {0011, 0101, 1001, 0110, 1010, 1100}
3: {0111, 1011, 1101, 1110}
4: {1111}
}
当然,我可以只为从 1 到 4 的 i 调用 combos(4, i)。但是,我想利用以下事实:
对于combos(4, i) 中的每个位集X,我们可以将位集X 中的一位从0 设置为1。
例如,0011 在 combos(4,2) 中,它会在 combos(4,3) 中生成 {1011, 0111},因为第一个和第二个最高有效位是 0。
编辑:这是我目前的完成方式:
def combos(set_, k):
return map(sum, itertools.combinations(set_, k)) # take combos of 1, 2, 4, 8 ... and the sums to get bitset back
def allCombos(n):
ret = {}
bitset = set([2**i for i in range(n)]) # generates 1, 2, 4, 8 ...
for k in range(1,n+1):
ret[k] = combos(bitset, k)
return k
【问题讨论】:
-
老实说,我不认为你的“捷径”特别有效。对于“列表
n”中的任何特定元素,“列表n-1”中的n元素可以设置一个位来给出该元素。如果你使用itertools.combinations,它真的很高效。 -
itertools.combinations 需要一个集合作为输入。我的输入将是一个整数(一个位集)。现在,我必须将我的位集转换为实际的 Python 集,调用 itertools.combinations,然后将该集转换回位集。效率太低了。
-
@martineau。我不认为这是重复的。此用户未尝试创建子集。他想要设置这么多位的数字,这是一个稍微不同的问题。
-
“快速方式”是相当主观的 - 您当前的方法有多快?当前方法的代码是什么样的?
标签: python combinations bitset