使用 Ruby/Erlang 迭代生成排列,无需递归或堆栈
Posted
技术标签:
【中文标题】使用 Ruby/Erlang 迭代生成排列,无需递归或堆栈【英文标题】:Generate permutations iteratively without recursion or stack with Ruby/Erlang 【发布时间】:2012-01-18 19:28:12 【问题描述】:我想生成列表的所有排列,但我想在将某些排列添加到堆栈或存储在任何地方之前过滤掉它们。
我将根据一些自定义的临时规则过滤掉排列。
换句话说,我想生成一个大列表(50-300 个元素)的排列列表,但我想在此过程中丢弃大部分生成的排列(我知道完整的数字排列的数量是N!
)。
我已经用它的Array.permutation.to_a
尝试了 Ruby,但它看起来在执行过程中维护了一个完整的堆栈,所以我很快就耗尽了内存 (8 GB)。
我也尝试过this Erlang 解决方案,但它的性能似乎与之前的 Ruby 类似。
这个问题有什么定制的解决方案吗?
附:我看过this和this,可惜我不懂C/C++。
【问题讨论】:
您可以使用一种称为“Steinhaus-Johnson-Trotter 算法”的算法通过迭代生成排列:en.wikipedia.org/wiki/… 您链接的第二个问题得到了一个很好的解决方案,应该很容易将其重写为 ruby。 听起来你想要的可能不是排列生成的路线,而是列表推导的路线。 TreyE,您能否详细说明一下使用列表推导式? 为什么要担心递归和堆栈?在 Erlang 中,递归是事物的自然顺序。 【参考方案1】:Ruby 的Array.permutation.to_a
确实生成了一个数组。那就不要使用to_a
!它的意思是“排列”。 Array.permutation
给你一个“枚举器”,一个生成器。由于您想丢弃大多数排列,请使用reject
。
res = [1,2,3,4].permutation(3).reject do |perm|
perm.first.even? #if this line is true, the perm will be rejected
end
将生成三个元素的所有排列,并拒绝第一个位置为偶数的那些。但是嗯……你见过多少300!是吗?
【讨论】:
谢谢,steenslag!我看过多少300!是:) 在回答前面关于列表推导的问题时,上面的内容非常相似。列表推导可以在许多方面被描述为与过滤器相结合的生成器。 steenslag 上面的定义与 one 非常相似。还 +1 以获得我不知道的出色答案 - 感谢您帮助我了解有关 ruby steenslag 的新知识!以上是关于使用 Ruby/Erlang 迭代生成排列,无需递归或堆栈的主要内容,如果未能解决你的问题,请参考以下文章