例如,单词“stack”,我想得到一个类似的数组:
['s', 'st', 'sta', ... 'stack', 't', 'ta', ... , 'c', 'ck', 'k']
我是通过这样的代码做到的:
def split_word(str)
result = []
chas = str.split("")
len = chas.size
(0..len-1).each do |i|
(i..len-1).each do |j|
result.push(chas[i..j].join)
end
end
result.uniq
end
有更好更干净的方法吗?感谢。
答案 0 :(得分:11)
def split_word s
(0..s.length).inject([]){|ai,i|
(1..s.length - i).inject(ai){|aj,j|
aj << s[i,j]
}
}.uniq
end
您还可以考虑使用Set
而不是Array来获得结果。
PS:这是基于阵列产品的另一个想法:
def split_word s
indices = (0...s.length).to_a
indices.product(indices).reject{|i,j| i > j}.map{|i,j| s[i..j]}.uniq
end
答案 1 :(得分:5)
我写道:
def split_word(s)
0.upto(s.length - 1).flat_map do |start|
1.upto(s.length - start).map do |length|
s[start, length]
end
end.uniq
end
groups = split_word("stack")
# ["s", "st", "sta", "stac", "stack", "t", "ta", "tac", "tack", "a", "ac", "ack", "c", "ck", "k"]
使用map
(功能)而不是模式 init empty + each + append + return (命令性)通常更清晰,更紧凑。
答案 2 :(得分:3)
不要这么认为。
这是我的尝试版本:
def split_word(str)
length = str.length - 1
[].tap do |result|
0.upto(length) do |i|
length.downto(i) do |j|
substring = str[i..j]
result << substring unless result.include?(substring)
end
end
end
end
答案 3 :(得分:3)
def substrings(str)
output = []
(0...str.length).each do |i|
(i...str.length).each do |j|
output << str[i..j]
end
end
output
end
这只是方法的清理版本,它可以使用更少的步骤=)
答案 4 :(得分:2)
def substrings(str)
(0...str.length).map do |i|
(i...str.length).each { |j| str[i..j]}
end
end
只是另一种方式,这对我来说更清楚。
答案 5 :(得分:1)
这是获取所有可能的子字符串的递归方法。
def substrings str
return [] if str.size < 1
((0..str.size-1).map do |pos|
str[0..pos]
end) + substrings(str[1..])
end
答案 6 :(得分:0)
之后的方式,但这是我重新格式化你的代码所得到的。
def substrings(string)
siz = string.length
answer = []
(0..siz-1).each do |n|
(n..siz-1).each do |i|
answer << string[n..i]
end
end
answer
end