我正在尝试编写一个函数,当给定整数x和字符串时,将返回每x个字符(包括空格)的换行符。
到目前为止,这是我的代码:
def add_newline(len, thing)
if thing.length <= len
return thing
else
thing.scan(/.{1, 4}/)
val = thing[0]
# (0..len).each { |x| thing[x] = "" }
return val + "\n" + add_newline(len, thing.to_s)
end
end
我甚至不知道这个问题是怎么发生的,只是看起来神奇的错误。这是一个例子:
puts add_newline 2, "1234"
#returns:
# 1
# 24
我不知道怎么可能。在我这之前:
def add_newline(len, thing)
if thing.length <= len
return thing
else
val = thing[0..len]
(0..len).each { |x| thing[x] = "" }
return val + "\n" + add_newline(len, thing)
end
end
这也没有用。它回来了:
puts add_newline 2, "1234"
#returns:
#123
#24
此时,我不知道还有什么可以尝试。如果有人可以帮助我,那将是惊人的。我也更喜欢保持递归。 (输入的任何字符串都不会来自用户,以防万一。)
答案 0 :(得分:2)
递归函数:
def add_new_line(len, thing)
return thing if thing.size < len || len < 1
head, tail = [thing.slice(0..len-1), thing.slice(len..thing.size)]
head.gsub(/^(.{#{len}})/, "\\1\n") + add_newline(len, tail)
end
好奇,为什么你更喜欢递归?是因为你认为这只能通过递归或迭代来解决,而递归是“更优雅”的吗?
因为非递归函数更优雅:
def add_newline(len, thing)
thing.gsub(/(.{#{len}})/, "\\1\n")
end
答案 1 :(得分:0)
让我计算一下可以获得预期结果的方法。这里有几个。
str = 'three blind mice'
len = 3
使用正则表达式
str.gsub(/(.{#{len}})/, '\1\n')
#=> "thr\\nee \\nbli\\nnd \\nmic\\ne"
请参阅String#gsub,尤其是使用反向引用。
采取程序方法:逐个字符地构建新字符串
(1..str.size).reduce('') do |s, i|
s << str[i-1]
s << '\n' if (i % len).zero?
s
end
# => "thr\\nee \\nbli\\nnd \\nmic\\ne"
请参阅Enumerable#reduce(又名inject
)。
s = str.dup
(len..len*(str.size/len)).step(len).reverse_each { |i| s.insert(i, '\n') }
s #=> "thr\\nee \\nbli\\nnd \\nmic\\ne"
请参阅Range#step和Enumerable#reverse_each。
将每个字符都链接到Enumerable#each_slice并链接到Enumerable#map以创建一个数组,然后Array#join'd。要形成新的字符串
str.each_char.each_slice(len).map { |a| a.size < len ? a.join : a.join << '\n' }.join
#=> "thr\\nee \\nbli\\nnd \\nmic\\ne"