如何生成长度在给定范围内的数组元素的所有可能组合?例如:
('a'..'f').to_a.all_possibilities(3, 5)
应该产生一个数组,如:
['abc', 'abd', 'abe', 'abf', ..., 'abcde', 'abcdf', 'abcda', ...]
包括从"abc"
(三个字符)到最后可能的('a'..'f').to_a
五个字符长度的组合。我不知道该怎么做。有什么帮助吗?
如何生成长度在给定范围内的数组元素的所有可能组合?例如:
('a'..'f').to_a.all_possibilities(3, 5)
应该产生一个数组,如:
['abc', 'abd', 'abe', 'abf', ..., 'abcde', 'abcdf', 'abcda', ...]
包括从"abc"
(三个字符)到最后可能的('a'..'f').to_a
五个字符长度的组合。我不知道该怎么做。有什么帮助吗?
Array#combination
是标准库:
[1] pry(main)> a = ('a'..'f').to_a
=> ["a", "b", "c", "d", "e", "f"]
[2] pry(main)> a.combination(3).to_a
=> [["a", "b", "c"],
["a", "b", "d"],
["a", "b", "e"],
["a", "b", "f"],
["a", "c", "d"],
["a", "c", "e"],
["a", "c", "f"],
["a", "d", "e"],
["a", "d", "f"],
["a", "e", "f"],
["b", "c", "d"],
["b", "c", "e"],
["b", "c", "f"],
["b", "d", "e"],
["b", "d", "f"],
["b", "e", "f"],
["c", "d", "e"],
["c", "d", "f"],
["c", "e", "f"],
["d", "e", "f"]]
如果您想要所有尺寸最小到最大的组合:
(min..max).flat_map{|size| a.combination(size).to_a }
如果您希望它们转换为字符串,只需替换.to_a
为.map(&:join)
.
(3..5).flat_map{|n| ('a'..'f').to_a.combination(n).map(&:join)}
编辑:为了满足 OP 的明确意图,使用repeated_permutation
.
(3..5).flat_map{|n| ('a'..'f').to_a.repeated_permutation(n).map(&:join)}
您可以通过这种方式修改我对您之前问题的回答以获得您想要的。
class Array
def all_possibilities(from, to)
(from..to).flat_map do |i|
if i < size
permutation(i).to_a
else
permutation(to - i).flat_map do |e|
(self + e).permutation.to_a
end
end
end.map(&:join)
end
end
array = ["F", "E", "R", "N", "A", "D", "O"]
array.all_possibilities(3, 8)
`
D = length of array
N = number of possible values. i.e a-z = 26
possible combinations = N ^ D
array = [possible values]
map26 = '0123456789abcdefghijklmnop'
map10 = 'abcdefghijklmnopqrstuvwxyz'
combo = ''
for 0...N ** D do |i|
i.to_s(D).split(//).each do |v|
combo += map10[map26.index(v)].chr
end
puts combo
combo = ''
end
`
编辑:请原谅上面的简洁,在浏览另一个答案时在 iPad 上破解它。我错了。
假设您希望 az 中的所有组合最多包含 3 列。
所有组合为 26 * 26 * 26 = 26 ** 3 = 17576
让数组的 0 个起点减去 1 = 17575
我们还需要一个映射变量,map26 是一列的 base 26 查找
map26 = '0123456789abcdefghijklmnop'
map10 = 'abcdefghijklmnopqrstuvwxyz'
回到我们的最大组合
17575.to_s(26)
=> "ppp"
从 map26 中提取 'p' 的索引并将其放入 map10 中:
map10[map26.index('p')] (add .chr for ruby ~ 1.8)
=> "z"
因此,如果您对上面的“ppp”进行切片和切块,您将获得最大的“zzz”组合
从映射变量中也可以看出“000”会映射到“aaa”
我已经修改了原始代码以包含这些更改。
关于原题,可以用D来控制字符串的最大长度,用for循环的起始值来控制最小长度。