2017-08-02 67 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錯誤。所以問題是,你的意見是什麼? `