如何在ruby中拆分字符串,如下面的示例所示?

如何在ruby中拆分字符串,如下面的示例所示?,ruby,string,split,Ruby,String,Split,我想将任意字符串转换为字符串数组。最好用一个例子来解释这种转换。如果字符串是“8737928”,我想返回以下数组 #=> ["8737928", # "8.737928", "87.37928", "873.7928", "8737.928", "87379.28", "873792.8", # "8.7.37928", "8.73.7928", "8.737.928", "8.7379.28", "8.73792.8", # "87.3.7928", "87.37.92

我想将任意字符串转换为字符串数组。最好用一个例子来解释这种转换。如果字符串是
“8737928”
,我想返回以下数组

#=> ["8737928",
#    "8.737928", "87.37928", "873.7928", "8737.928", "87379.28", "873792.8",
#    "8.7.37928", "8.73.7928", "8.737.928", "8.7379.28", "8.73792.8",
#    "87.3.7928", "87.37.928", "87.379.28", "87.3792.8", "873.7.928",
#    "873.79.28", "873.792.8", "8737.9.28", "8737.92.8", "87379.2.8",
#    "8.7.3.7928", "8.7.37.928", "8.7.379.28", "8.7.3792.8", "8.73.7.928",
#    "8.73.79.28", "8.73.792.8", "8.737.9.28", "8.737.92.8", "8.7379.2.8",
#    "87.3.7.928", "87.3.79.28", "87.3.792.8", "87.37.9.28", "87.37.92.8",
#    "87.379.2.8", "873.7.9.28", "873.7.92.8", "873.79.2.8", "8737.9.2.8",
#    "8.7.3.7.928", "8.7.3.79.28", "8.7.3.792.8", "8.7.37.9.28",  "8.7.37.92.8",
#    "8.7.379.2.8", "8.73.7.9.28", "8.73.7.92.8", "8.73.79.2.8", "8.737.9.2.8",
#    "87.3.7.9.28", "87.3.7.92.8", "87.3.79.2.8", "87.37.9.2.8", "873.7.9.2.8",
#    "8.7.3.7.9.28", "8.7.3.7.92.8", "8.7.3.79.2.8", "8.7.37.9.2.8",
#    "8.73.7.9.2.8", "87.3.7.9.2.8",
#    "8.7.3.7.9.2.8"]
如您所见,在0和6之间(
“8737928”。size-1#=>6
)小数点插入字符串中,在1和6之间的每个索引组合处。由于小数点可能跟在每个字符后面,也可能不跟在最后一个字符后面,因此数组包含
2**6#=>64个
元素

我如何才能做到这一点?

解决方案1
def doit(str)
  indices = (1..str.size-1).to_a
  indices.each_with_object([str]) { |ndots, combos|
    indices.combination(ndots).each { |sub| combos << dotify(str, sub) } }
end

def dotify(str, indices)
  indices.reverse.each_with_object(str.dup) { |i,s| s.insert(i,'.') }
end

doit("8737928").size
  #=> 64 

doit "8737928"
  #=> ["8737928",
  #    "8.737928", "87.37928", "873.7928", "8737.928", "87379.28", "873792.8",
  #    "8.7.37928", "8.73.7928", "8.737.928", "8.7379.28", "8.73792.8",
  #    "87.3.7928", "87.37.928", "87.379.28", "87.3792.8", "873.7.928",
  #    "873.79.28", "873.792.8", "8737.9.28", "8737.92.8", "87379.2.8",
  #    "8.7.3.7928", "8.7.37.928", "8.7.379.28", "8.7.3792.8", "8.73.7.928",
  #    "8.73.79.28", "8.73.792.8", "8.737.9.28", "8.737.92.8", "8.7379.2.8",
  #    "87.3.7.928", "87.3.79.28", "87.3.792.8", "87.37.9.28", "87.37.92.8",
  #    "87.379.2.8", "873.7.9.28", "873.7.92.8", "873.79.2.8", "8737.9.2.8",
  #    "8.7.3.7.928", "8.7.3.79.28", "8.7.3.792.8", "8.7.37.9.28",  "8.7.37.92.8",
  #    "8.7.379.2.8", "8.73.7.9.28", "8.73.7.92.8", "8.73.79.2.8", "8.737.9.2.8",
  #    "87.3.7.9.28", "87.3.7.92.8", "87.3.79.2.8", "87.37.9.2.8", "873.7.9.2.8",
  #    "8.7.3.7.9.28", "8.7.3.7.92.8", "8.7.3.79.2.8", "8.7.37.9.2.8",
  #    "8.73.7.9.2.8", "87.3.7.9.2.8",
  #    "8.7.3.7.9.2.8"] 
经过进一步思考(参见下面的原始解决方案,可能不正确),OP真正想要做的似乎是在字符串中的每个可能的位置组合处插入点。这里有一种方法可以做到:

def splits(str, prefix="")
  c = str.size - 1
  (0..c).flat_map do |m|
    (0...c).to_a.combination(m).map do |n|
      n.each_with_object(str.dup) {|i,s| s.insert(c-i, ?.) }
    end
  end
end

puts splits("8737928")
# => 8737928
#    873792.8
#    87379.28
#    87379.2.8
#    8737.928
#    8737.92.8
#    8737.9.28
#    8737.9.2.8
#    873.7928
#    873.792.8
#    873.79.28
#    873.79.2.8
#    873.7.928
#    873.7.92.8
#    873.7.9.28
#    873.7.9.2.8
#    87.37928
#    87.3792.8
#    87.379.28
#    87.379.2.8
#    87.37.928
#    87.37.92.8
#    87.37.9.28
#    87.37.9.2.8
#    87.3.7928
#    87.3.792.8
#    87.3.79.28
#    87.3.79.2.8
#    87.3.7.928
#    87.3.7.92.8
#    87.3.7.9.28
#    87.3.7.9.2.8
#    8.737928
#    8.73792.8
#    8.7379.28
#    8.7379.2.8
#    8.737.928
#    8.737.92.8
#    8.737.9.28
#    8.737.9.2.8
#    8.73.7928
#    8.73.792.8
#    8.73.79.28
#    8.73.79.2.8
#    8.73.7.928
#    8.73.7.92.8
#    8.73.7.9.28
#    8.73.7.9.2.8
#    8.7.37928
#    8.7.3792.8
#    8.7.379.28
#    8.7.379.2.8
#    8.7.37.928
#    8.7.37.92.8
#    8.7.37.9.28
#    8.7.37.9.2.8
#    8.7.3.7928
#    8.7.3.792.8
#    8.7.3.79.28
#    8.7.3.79.2.8
#    8.7.3.7.928
#    8.7.3.7.92.8
#    8.7.3.7.9.28
#    8.7.3.7.9.2.8
解决方案2 然而,尽管@EliSadoff的解决方案没有被推广,我还是喜欢他的“周期的每个点都可以是一个布尔决定”的想法。如果我们考虑到字符串中的位置,在该位置我们可以插入一个周期作为二进制数m中的位,长度与字符串长度相同(基数2),我们可以简单地从0迭代到2(c-1)-1(其中c是字符串的长度)以获取每个可能的此类数字。例如,如果我们的字符串是
“abcd”
(c=4),则我们可以从0迭代到7(2(4-1)-1)以找到每个周期的位置:

m₁₀ | M₂ 4 2 1 | 4 2 1 |结果
─────┼────┴─┴─┴─┼───┴───┴───┴───┼─────────
0│    0 0 0 │ a、b、c、d│ abcd
1.│    0 0 1 │ a b c•d | abc.d
2.│    0 1 0 │ a b•c d | ab.cd
3.│    0 1 1 │ a b•c•d | ab.c.d
4.│    1 0 0 │ a•b c d | a.bcd
5.│    1 0 1 │ a•b c•d | a.bc.d
6.│    1 1 0 │ a•b•c d | a.b.cd
7.│    1 1 1 │ a•b•c•d | a.b.c.d
唯一缺少的部分是根据第二列中的位插入句点。这很容易:为了确定是否需要在位置n插入句点,我们测试m中的第n位是否为1。为此,我们可以使用逐位操作m&(1)≪ n)

将所有这些放在一起,我们得到以下结果:

def splits2(str)
c=str.size-1
(0…2**c)图do | m|
0.高达(c).带_对象(str.dup)do | i,s|
s、 如果m和(10),则插入(c-i,?)
结束
结束
结束
解决方案3 为了好玩,这里有另一个解决方案,它也使用二进制数方法,但方式不同。我将把它作为练习留给读者,让他们了解它是如何工作的:

def splits3(str)
c=str.size-1
(0…2**c)图do | m|
点=(“%*b”%[c,m])。每个字符映射(&{1=>?。})
str.each_char.zip(点)。连接
结束
结束
原液 与@CarySwoveland的解决方案类似,但我认为更简单一点:

def拆分(str,pfx=”“)
如果str.empty返回[]?
(1…str.size).map{i|pfx+str.dup.insert(i,,)}+
拆分(str[1..-1],“#{pfx}#{str[0]}”。)
结束
p分割(“8737928”)
# => [ "8.737928", "87.37928", "873.7928", "8737.928", "87379.28", "873792.8",
#      "8.7.37928", "8.73.7928", "8.737.928", "8.7379.28", "8.73792.8",
#      "8.7.3.7928", "8.7.37.928", "8.7.379.28", "8.7.3792.8",
#      "8.7.3.7.928", "8.7.3.79.28", "8.7.3.792.8",
#      "8.7.3.7.9.28", "8.7.3.7.92.8",
#      "8.7.3.7.9.2.8"
#     ]

要求不明确,我得出的结果与Cary和Jordan的结果不同:

 def dot_it(prefix, suffix = nil)
   return dot_it(prefix[0], prefix[1..-1]) if suffix.nil? # first call

   (1...suffix.length).flat_map do |i|
     sp, ss = "#{prefix}.#{suffix[0...i]}", suffix[i..-1]
     ["#{sp}.#{ss}", dot_it(sp, ss)].flatten.compact
   end
end
dot_it("8737928")
#⇒ ["8.7.37928", "8.7.3.7928", "8.7.3.7.928", "8.7.3.7.9.28",
#   "8.7.3.7.9.2.8", "8.7.3.7.92.8", "8.7.3.79.28", "8.7.3.79.2.8",
#   "8.7.3.792.8", "8.7.37.928", "8.7.37.9.28", "8.7.37.9.2.8",
#   "8.7.37.92.8", "8.7.379.28", "8.7.379.2.8", "8.7.3792.8",
#   "8.73.7928", "8.73.7.928", "8.73.7.9.28", "8.73.7.9.2.8",
#   "8.73.7.92.8", "8.73.79.28", "8.73.79.2.8", "8.73.792.8",
#   "8.737.928", "8.737.9.28", "8.737.9.2.8", "8.737.92.8",
#   "8.7379.28", "8.7379.2.8", "8.73792.8"]
我的方法是:

dot_it("8737928").count
#⇒ 31

上面的两个答案都给出了21个结果。谁是对的?

你想循环这个还是拆分一个字符串?我想循环兄弟。我希望所有的输出都是这样。对不起,因为我不擅长英语。感谢每个人的答案是一个很好的姿态,但是,我认为,这是不明智的。首先,如果感谢每个人,即使是作者,也没有多大意义f糟糕的答案。第二,如果有人给出了一个非常糟糕的答案,而你却不感谢他们,你不妨说,“你的答案糟透了”。第三,这对每个阅读评论的人来说都是(轻微的)时间浪费。看看其他问题,你会发现这只是没有完成(也没有预料到)。谢谢。我是beginer。我会小心的。我相信我现在理解了这个问题。问题是,您没有显示足够的数组元素以返回给读者,让读者理解您想要的内容。我冒昧地编辑了这个问题。我相信您不会介意,我所写的内容准确地描述了您的意图。我有投票权d重新打开问题。我相应地修改了我的答案。非常感谢。我已经修改了我的答案,以反映我目前对问题的理解。非常感谢,这是一个改进。我已经编辑了我的答案,包括三个我认为符合OP意图的解决方案。非常感谢你的代码为6,方法名称为4。但是我的fReStand说这个问题给出了64个结果。我正在尝试这样做。回顾这64个结果会很棒。“CalySwitoValand我会说方法名称比解决方案更优雅,你应该考虑将评估结果替换为方法名称的6,2在评论中开始有趣的聊天,2用于代码。
dot_it("8737928").count
#⇒ 31