在 Erlang 或 Ruby 中生成集合的幂集而不保留堆栈
我想生成一个相当大的集合(大约 30-50 个元素)的幂集,并且我知道需要 2^n
来存储幂集。
是否可以一次生成一个子集?
即通过迭代生成一个集合的幂集,将每个生成的子集保存到磁盘/数据库,将其从堆栈/内存中删除,然后才继续生成其他子集?
I would like to generate a powerset of a rather big set (about 30-50 elements) and I know that it takes 2^n
to store the powerset.
Is it possible to generate one subset at a time?
I.e. generate a powerset of a set with iterations, saving each generated subset to disk/database, removing it from the stack/memory and only then continuing to generate other subsets?
Unfortunately I have failed to modify Erlang and Ruby examples to my needs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编辑:如果没有给出块,则添加枚举器(如@Jörg W Mittag)。
输出
Edit: Added the enumerator (as @Jörg W Mittag) if no block is given.
Output
生成列表幂集的一种方法(实际上是您的 Erlang 示例使用的方法)是迭代从 0 到 2^n(不包括)的所有数字
x
,并且对于每个x
,当且仅当x
的第i
位时,生成包含原始列表的第i
个元素的列表> 已设置。由于使用此方法生成当前列表仅取决于
x
的值,而不取决于任何先前生成的列表,因此您不必在使用列表后将它们保留在内存中。所以这个方法可以用来做你想做的事。One way to generate a powerset of a list (which is in fact the one that your Erlang example uses) is to iterate over all numbers
x
from 0 to 2^n (exclusive) and for eachx
, generate the list that contains thei
th element of the original list if and only if thei
th bit ofx
is set.Since using this approach generating the current list only depends on the value of
x
and not on any of the previously generated lists, you don't have to keep the lists in memory after using them. So this approach can be used to do what you want.它使用标准的“位数组”技巧来生成幂集(并且它使用了 Ruby 的 Integer 表现为位数组的事实)。但更重要的是,它使用
Enumerator
来延迟生成集合。即使对于数千个元素,这也能完美工作:
编辑:这是基于@steenslag的解决方案。我完全忘记了 Array#combination,因为我太专注于寻找适用于任何
Enumerable
的解决方案。但是,我的解决方案要求Enumerable
无论如何都是有限的,并且任何有限的Enumerable
都应该可以表示为Array
,所以这并不是什么问题。一个限制。This uses the standard "bit array" trick for generating power sets (and it uses the fact that Ruby's
Integer
s behave as bit arrays). But more importantly, it uses anEnumerator
to generate the sets lazily.This works perfectly fine even for thousands of elements:
EDIT: This is based on @steenslag's solution. I totally forgot about
Array#combination
, since I was too focused on finding a solution that would work for anyEnumerable
. However, my solution requires that theEnumerable
be finite anyway, and any finiteEnumerable
should probably be representable as anArray
, so that's not much of a restriction.