你所询问的有一个名称,它被称为幂集。
在Google上搜索"幂集算法"会导向这个递归解决方案。
Ruby算法
def powerset!(set)
return [set] if set.empty?
p = set.pop
subset = powerset!(set)
subset | subset.map { |x| x | [p] }
end
幂集直觉
如果S = (a, b, c),那么幂集(S)是所有子集的集合
幂集(S) = {(), (a), (b), (c), (a,b), (a,c), (b,c), (a,b,c)}
第一个“技巧”是尝试递归定义。
什么是停止状态?
S = () 时,幂集(S)是什么?
如何达到它?
减少一个元素的集合
考虑取出一个元素 - 在上面的例子中,取出{c}
S = (a,b) 然后 幂集(S) = {(), (a), (b), (a,b)}
缺少什么?
幂集(S) = {(c), (a,c), (b,c), (a,b,c)}
嗯
注意到任何相似之处吗? 再看一遍...
幂集(S) = {(), (a), (b), (c), (a,b), (a,c), (b,c), (a,b,c)}
取出任何一个元素
幂集(S) = {(), (a), (b), (c), (a,b), (a,c), (b,c), (a,b,c)} 是
powerset(S - {c}) = {(), (a), (b), (a,b)}并上
{c} U powerset(S - {c}) = { (c), (a,c), (b,c), (a,b,c)}
powerset(S) = powerset(S - {ei}) U ({ei} U powerset(S - {ei}))
其中ei是S的元素(一个单独的元素)
伪算法
- 传递的集合是否为空?完成(请注意,空集的幂集是{{}})
- 如果非空,则取出一个元素
- 对剩余的集合进行递归调用该方法
- 返回由以下两个部分组成的集合:
- 不包含该元素的集合的幂集(来自递归调用)
- 这个相同的集合(即2.1),但其中的每个元素都与最初取出的元素结合