如何在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