【问题标题】:Appending array while using recursive loop in Ruby在Ruby中使用递归循环时附加数组
【发布时间】:2016-11-02 23:36:19
【问题描述】:

我正在使用 Ruby 处理 Collatz Conjecture,并在 n = 1 处停止。 这是我到目前为止的代码:

def collatz(n)
  arr = []
  if n == 1
    arr << n
    return arr
  elsif n % 2 == 0
    n = n / 2
    arr << n
    collatz(n)
  else
    n = (3 * n) + 1
    arr << n
    collatz(n)
  end

end

我希望代码在整个循环中返回一个包含所有 n 值的数组。 例如,如果我做collatz(10),我希望它显示[5,16,8,4,2,1]

现在它为任何输入值显示[1]。这是因为在第一个循环之后,它调用 collat​​z(n),并且第一行显示arr= [],从而在每个循环中重置我的数组。

如何在追加数组的同时继续方法循环?

【问题讨论】:

    标签: arrays ruby recursion


    【解决方案1】:

    将数组添加到参数中,例如:

    def collatz(arr, n)
      if n == 1
        arr << n
        return arr
      elsif n % 2 == 0
        n = n / 2
        arr << n
        collatz(arr, n)
      else
        n = (3 * n) + 1
        arr << n
        collatz(arr, n)
      end
    end
    
    puts "#{collatz([], 10).join(', ')}"
    

    结果会如你所愿:

    [5, 16, 8, 4, 2, 1, 1]
    

    但请记住:递归是邪恶的!

    在递归内:

    def collatz(n)
      arr = []
      loop do
        n = n % 2 == 0 ? n / 2 : (3 * n) + 1
        arr << n
        break if n == 1
      end
      arr
    end
    
    puts "#{collatz(10).join(', ')}"
    

    【讨论】:

    • 为什么递归是邪恶的?
    • 递归是邪恶的,因为它通过最大调用堆栈限制限制了你的能力。它(调用堆栈限制)取决于您的语言和计算机,但不是无限的。
    【解决方案2】:

    您可以使用此代码。

    如果 n 为 1,则像 Array 一样返回它。 如果 n % 2 == 0 使用 n / 2 否则使用 (3 * n) + 1。 如果 n 现在是 1,则像 Array 一样返回它,否则用 n 值定义新的 Array 并用新的 n 调用自己。

    def collatz(n)
      return [n] if n == 1
      n = n % 2 == 0 ? n / 2 : (3 * n) + 1
      n == 1 ? [n] : [n] + send(__method__, n)
    end
    

    输出

    p collatz(10)
    # => [5, 16, 8, 4, 2, 1]
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2021-04-03
      • 1970-01-01
      • 2013-10-24
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-14
      • 1970-01-01
      相关资源
      最近更新 更多