我想知道这个用于生成排列的函数的惯用版本在Ruby中会是什么样子。我知道[1,2,3].permutation.to_a
将产生相同的结果,但我更感兴趣的是学习Ruby以及如何在Ruby中处理这样的递归问题。
def permutations(seq)
if seq.empty? || seq.count == 1
seq
else
seq.map { |x|
permutations(seq.select { |e| e != x }).map { |p|
if p.class == Fixnum
[x, p]
else
p.unshift(x)
end
}
}.flatten(1)
end
end
谢谢!
答案 0 :(得分:4)
class Array
def permutations
return [self] if size < 2
perm = []
each { |e| (self - [e]).permutations.each { |p| perm << ([e] + p) } }
perm
end
end
[1, 2, 3].permutations #=> [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
来源:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/32844
编辑:为避免猴子修补,请将其放入模块中:
module ArrayExtensions
def permutations
#snip
end
end
Array.send :include, ArrayExtensions
答案 1 :(得分:0)
在Ruby(特别是Rails)中将这样的功能直接添加到核心类中是很常见的。
该方法的一种替代方案是单独的静态实用程序模块:
module ArrayUtils
def self.permute(array)
return [array] if array.size < 2
array.flat_map do |elem|
permute(array - [elem]).map do |perm|
([elem] + perm)
end
end
end
end
ArrayUtils.permute [1, 2, 3]
# => [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]