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

Posted

技术标签:

【中文标题】ruby - 如何从字符串数组中生成可能的字母顺序组合?【英文标题】:ruby - how to generate the possible sequential combination of letters from an array of strings? 【发布时间】:2014-04-21 04:07:57 【问题描述】:

我有一个字符串数组:

["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"

【问题讨论】:

不清楚你指定的数组遵循什么规则。此外,您写了您想要的组合,但这似乎与您想要"AG" 而不是"GA" 相矛盾。问题不清楚。 顺序组合请:) @sawa 有道理。也不清楚是什么决定了组合的长度。你只想组合字符串数组的长度吗? 【参考方案1】:

这是你需要的:

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)

【讨论】:

在这种情况下,为什么要使用flat_map 而不是简单的map 这是一个错误,同时将其编辑掉。实际上flat_map 也可以,只是不需要。 好的,很酷。我很好奇并了解了 :product:flat_map 做了什么。没想到我能做到。干杯! 这行得通,但我认为应该有更有效的方法。 效率如何?这是一个易于阅读、易于理解的短代码行,程序员只需 5 秒即可编写完成。除了所需的输出之外,您从未在问题中陈述过任何其他内容。请接受我的回答,因为这确实有效,如果您有特定需求,请提交一份新的。【参考方案2】:
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

【讨论】:

我刚开始写这样的东西.. 为什么不用#split @ArupRakshit 你的意思是代替each_char?这是一种更间接的方式。 @sawa 那么s.scan(/./) 会怎么样?如果它工作,那么你不需要输入 - s.each_char.to_a.. :-) @ArupRakshit 我不是在打代码高尔夫。我优先考虑概念的简单性,而不是减少我必须输入的字符数。 顺便说一句,在我的基准测试中使用 map(&:chars)map |s| s.each_char.to_a 快约 10%。【参考方案3】:

递归解决方案:

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"]

【讨论】:

我认为您的意思是“非破坏性”。 (当然,因为map 是非破坏性的,所以不需要dup :) -2 为我,安德鲁,但为您 -1,因为第一次没有看到。 你给自己-1 ..你太大胆了.. :p +1 看起来不错,虽然我尝试了一个长字并得到了doit(["MUMMIFICATION"]) SystemStackError: stack level too deep

以上是关于ruby - 如何从字符串数组中生成可能的字母顺序组合?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中生成顺序整数的列表或数组?

如何使用 Perl 从一组字母中生成单词列表?

ruby:对符号数组进行排序

如何使用指针从2D char数组中生成一个句子

如何在 Ruby-on-Rails 中生成 PDF 表单

在Java中生成字母数字随机字符串[重复]