我正在从旧的试卷上做这个问题,以了解我的红宝石编程技巧。我在第2部分遇到了一些问题.Seq_gen_b - >使用递归生成序列。以下是问题本身。
基本上它要求通过取一个值n,乘以2并取走3来生成一系列数字。然后使用这个新数字生成下一个数字。这些数字将存储在一个数组中。我的问题是,我想不出一个阻止递归发生的好方法。
创建两个方法 - seq_gen_a和seq_gen_b - 每个方法都会 取一个数,n(> 2),并生成一个四的数组 元素,其第一个元素是n,接下来的三个元素是三个元素 序号中的数字是前一个数字加倍并且为3 从中;这样,(i)seq_gen_a使用生成序列 迭代,以及(ii)seq_gen_b使用递归生成序列。 例如,给定数字5,这两种方法都将输出: [5,7,11,19]但是,显然,他们将实现这一输出 不同的方式
这是我到目前为止所做的,但我无法弄清楚如何阻止它耗尽内存。这可能是完全错误的
def seq_gen_b(n)
if n < 2
n
else
(0..2).each do |i|
num = ((n * 2) -3)
seq_gen_b(num)
end
end
end
非常感谢任何帮助,并提前致谢
答案 0 :(得分:2)
就个人而言,我认为这两种设计都不是很好。生成序列,并选择从中获取多少元素,是两个非常不同的问题,不应该在一个方法中混淆。
为了生成序列,Ruby已经有Enumerator
类:
n = 5
e = Enumerator.new do |y| loop do y << n; n = 2*n - 3 end end
e.next # => 5
e.next # => 7
e.next # => 11
e.next # => 19
我会将两个不同的关注点分成两个不同的方法,一个返回生成器,另一个选择要采用的元素。 Enumerator
混合Enumerable
,因此我们也可以使用所有这些方法,包括take
。这意味着我们已经为我们编写了选择要采用多少元素的方法。多好! (当你使用正确的抽象时会发生这种情况。)
def seq_gen(n) Enumerator.new do |y| loop do y << n; n = 2*n - 3 end end end
def seq_5_take_4; seq_gen(5).take(4) end
seq_5_take_4
# => [5, 7, 11, 19]
答案 1 :(得分:1)
在进行递归调用之前,所有方法需求都是实际停止条件:
def seq_gen_b(n)
result = [n]
seq_gen_b_helper(n, result, 3)
end
def seq_gen_b_helper(n, result, count)
if count != 0
value = ((n * 2) - 3)
result << value
seq_gen_b_helper(value, result, count - 1)
else
result
end
end
因为你应该再做三个对象,所以只需使用一个简单的计数器就可以确定你是否处于正确的数量,然后返回。
答案 2 :(得分:1)
我认为使用单个方法是最干净的,理想情况下使用可选参数。我的解决方案如下:
def seq_gen_b(n, result=[])
return result if result.count >=4
result << n
seq_gen_b((n*2)-3, result)
end
答案 3 :(得分:0)
这是你可以做到的一种方式:
def seq_gen_b(n, a=[*n])
a.size==4 ? a : seq_gen_b(nil, a << a.last*2-3)
end
seq_gen_b(5)
#=> [5, 7, 11, 19]
如果[*n]
是数组,则 n
会返回n
,如果[n]
是整数,则n
会返回nil
。 {{1}}只是一个占位符;任何价值都可以。