ruby - 如何从字符串数组生成可能的顺序字母组合?

时间:2014-03-15 20:13:12

标签: ruby arrays tuples combinations

我有一个字符串数组:

["ABC", "GHI"]

广告我想要所有的'字母'组合,从左到右读取,即

["AG", "AH", "AI", "BG", "BH", "BI", "CG", "CH", "CI"]

但不是

"GA", "GB", "HA", etc.

类似地,

["ABC", "DEF", "GHI"]

应生成

["ADG", "ADH", "ADI", "AEG", "AEH", "AEI", "AFG", "AFH", "AFI", "BDG", "BDH", 
"BDI", "BEG", "BEH", "BEI", "BFG", "BFH", "BFI", "CDG", "CDH", "CDI", "CEG", 
"CEH", "CEI", "CFG", "CFH" "CFI"]

但不是

"DAG", "GAD" or "GFA"

3 个答案:

答案 0 :(得分:7)

这就是你需要的:

a = ["ABC","DEF", "GHI"]
a.map(&:chars).reduce(&:product).map(&:join)

顺便说一句,你在示例输出中出现了一些错误,根据你的规范,永远不应该有以E或F开头的字符串。所以我想而不是"ECH", "ECI", "FCG", "FCH", "FCI"你的意思是"CEH", "CEI", "CFG", "CFH", "CFI"

修改

chars返回一个枚举器,而不是一个数组,而在2.0之前的Ruby版本中,它们没有product方法。因此,在这些版本中,只需使用to_a,如下所示:

a.map(&:chars).map(&:to_a).reduce(&:product).map(&:join)

答案 1 :(得分:4)

a = ["ABC","DEF", "GHI"]
first, *rest = a.map{|s| s.each_char.to_a}
first.product(*rest).map(&:join)
# =>
# ["ADG", "ADH", "ADI", "AEG", "AEH", "AEI", "AFG", "AFH", "AFI", "BDG", "BDH", "BDI",
# "BEG", "BEH", "BEI", "BFG", "BFH", "BFI", "CDG", "CDH", "CDI", "CEG", "CEH", "CEI",
# "CFG", "CFH", "CFI"]

基准与@ ggPeti的解决方案比较:

t = Time.now
50000.times do
  a.map(&:chars).reduce(&:product).map(&:join)
end
puts Time.now - t
# => 2.037303374

t = Time.now
50000.times do
  first, *rest = a.map{|s| s.each_char.to_a}
  first.product(*rest).map(&:join)
end
puts Time.now - t
# => 1.670047516

答案 2 :(得分:1)

递归解决方案:

def doit(b)
  recurse(b.map(&:chars))
end

def recurse(a)
  (a.size==2 ? a.first.product(a.last) :a.shift.product(recurse a)).map(&:join)
end

doit(["ABC", "DEF", "GHI"])  
  #=> ["ADG", "ADH", "ADI", "AEG", "AEH", "AEI", "AFG", "AFH", "AFI",
  #    "BDG", "BDH", "BDI", "BEG", "BEH", "BEI", "BFG", "BFH", "BFI",
  #    "CDG", "CDH", "CDI", "CEG", "CEH", "CEI", "CFG", "CFH", "CFI"] 

doit(["ABC", "DE", "FGHI"])
  #=> ["ADF", "ADG", "ADH", "ADI", "AEF", "AEG", "AEH", "AEI",
  #    "BDF", "BDG", "BDH", "BDI", "BEF", "BEG", "BEH", "BEI",
  #    "CDF", "CDG", "CDH", "CDI", "CEF", "CEG", "CEH", "CEI"]