2017-08-02 30 views
-1

我很抱歉,但我想不出好标题的arr.last返回nil递归add_numbers

我的问题是,为什么这个递归函数数组中的工作添加的数字:

def add_numbers(arr) 
    return arr.first if arr.size == 1 
    return nil if arr.empty? 


    arr.pop + add_numbers(arr[0..-1]) 
end 

,但不是这一个:

def add_numbers(arr) 
    return arr.first if arr.size == 1 
    return nil if arr.empty? 

    arr = arr[0...-1] 
    arr.last + add_numbers(arr[0..-1]) 
end 

我收到的错误是

TypeError: nil can't be coerced into Fixnum 

因为arr.last在最后一步是零,我想。我试着在纸上做一个记忆模型,但我仍然不知道为什么第一个不等于第二个。

感谢

回答

0

在我的情况下,它的工作很好,但一个坏的结果,问题是使用:的

arr = arr[0...-1] 

代替

arr.pop 

与流行修改编曲做小输出最后一个数字并返回最后一个数字,另一个在得到最后一个数字之前得到的数组更小:

分别

def add_numbers(arr) 

     puts "array = #{arr}" 
     puts "length = #{arr.length}" 

     return arr.first if arr.size == 1 
     return nil if arr.empty? 


     arr.pop + add_numbers(arr[0..-1]) 
    end 

    def add_numbers(arr) 

     puts "array = #{arr}" 
     puts "length = #{arr.length}" 


     return arr.first if arr.size == 1 
     return nil if arr.empty? 

     arr = arr[0...-1] 
     arr.last + add_numbers(arr[0..-1]) 
    end 

与下面的输出:

[32] pry(main)> a = [1,2,3,4,5] 
    => [1, 2, 3, 4, 5] 
    [33] pry(main)> a.pop 
    => 5 
    [34] pry(main)> a 
    => [1, 2, 3, 4] 
    [35] pry(main)> a = [1,2,3,4,5] 
    => [1, 2, 3, 4, 5] 
    [36] pry(main)> a = a[0...-1] 
    => [1, 2, 3, 4] 
    [37] pry(main)> a.last 
    => 4 

让一些调试器添加到您的功能

[1] pry(main)> 
[1] pry(main)* => :add_numbers 
[2] pry(main)> add_numbers [1, 2, 3, 4, 5] 
array = [1, 2, 3, 4, 5] 
length = 5 
array = [1, 2, 3, 4] 
length = 4 
array = [1, 2, 3] 
length = 3 
array = [1, 2] 
length = 2 
array = [1] 
length = 1 
=> 15 
[11] pry(main)> 
[11] pry(main)* => :add_numbers 
[12] pry(main)> add_numbers [1, 2, 3, 4, 5] 
array = [1, 2, 3, 4, 5] 
length = 5 
array = [1, 2, 3, 4] 
length = 4 
array = [1, 2, 3] 
length = 3 
array = [1, 2] 
length = 2 
array = [1] 
length = 1 
=> 11 

所以你应该最后一个功能更改为类似这样:

def add_numbers(arr) 

    puts "array = #{arr}" 
    puts "length = #{arr.length}" 


    return arr.first if arr.size == 1 
    return nil if arr.empty? 

    arr.last + add_numbers(arr[0...-1]) 
end 

以下输出

[39] pry(main)> add_numbers [1, 2, 3, 4, 5] 
array = [1, 2, 3, 4, 5] 
length = 5 
array = [1, 2, 3, 4] 
length = 4 
array = [1, 2, 3] 
length = 3 
array = [1, 2] 
length = 2 
array = [1] 
length = 1 
=> 15 
0

假设

arr = [1,2,3] 

在第一种情况下,

last = arr.pop 
    #=> 3 
arr 
    #=> [1,2] 
arr[0..-1] 
    #=> [1,2] 
last + add_numbers(arr[0..-1]) 
    #=> 3 + add_numbers([1,2]) 

在第二种情况下,

arr[0..-1] 
    #=> [1,2,3] 
arr = arr[0...-1] 
    #=> [1,2] 
arr[0..-1] 
    #=> [1,2] 
arr.last + add_numbers(arr[0..-1]) 
    #=> 2 + add_numbers([1,2]) 
0

在范围,..是包含的,...是排他性的。如果arr = [1, 2, 3]arr[0..-1] == [1, 2, 3]arr[0...-1] == [1, 2]

关于第二个方法的第一次迭代,这里是你的最后一行

2 + add_numbers([1, 2]) 

相比之下,与你的工作方法

3 + add_numbers([1, 2]) 

你一定会与结束错误的结果,但如果所有输入都是整数,则不应得到nil错误。所以问题是,你的意见是什么? `