在Ruby中生成数字序列

时间:2014-12-17 16:21:39

标签: ruby recursion

我正在从旧的试卷上做这个问题,以了解我的红宝石编程技巧。我在第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

非常感谢任何帮助,并提前致谢

4 个答案:

答案 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}}只是一个占位符;任何价值都可以。