哪裏會發生這種情況?
你的錯誤
stockpicker.rb:8:in `block in stock_picker': undefined method `-' for nil:NilClass (NoMethodError)
from stockpicker.rb:7:in `each'
from stockpicker.rb:7:in `stock_picker'
from stockpicker.rb:29:in `<main>'
是在8號線發生
if prices[i] - prices[day] > profit
當它試圖訪問prices[i]
當i = 9
和prices
回報nil
, 不迴應歌劇減去-
TOR。
爲什麼會發生這種情況?
你是一個循環
(0...i).each do |day|
if prices[i] - prices[day] > profit
min_day , max_day , profit = day , i , prices[i] - prices[day]
end
#i += 1
end
這裏增加i
指數計數器變量並沒有真正意義內的循環,因爲 的day
已經在範圍(0...i)
和 增加i
遍歷值在這個循環內意味着它將prices
數組中的每個值與內部的prices
內的下一個day
值一次進行比較陣列,這 僅包括prices
的前三個值(在 意的值prices
數組的末尾,如1
和10
永遠不會對 彼此進行比較);例如
i = 1
prices = [17,3,6,9,15,8,6,1,10]
# iteration 0
if prices[i] - prices[day] > profit
# 3 - 17 > 0 # => false
# iteration 1
i += 1 # => 2
day # => 0
if prices[i] - prices[day] > profit
# 6 - 17 > 0 # => false
i += 1 # => 3
day # => 1
# iteration 2
if prices[i] - prices[day] > profit
# 9 - 3 > 0 # => true
min_day, max_day, profit = 1, 3, 6
i += 1 # => 4
day # => 0
# iteration 3
if prices[i] - prices[day] > profit
# 15 - 17 > 0 # => false
i += 1 # => 5
day # => 1
# iteration 4
if prices[i] - prices[day] > profit
# 8 - 3 > 0 # => true
min_day, max_day, profit = 1, 5, 5
i += 1 # => 6
day # => 2
# iteration 5
if prices[i] - prices[day] > profit
# 6 - 6 > 0 # => false
i += 1 # => 7
day # => 3
# iteration 6
if prices[i] - prices[day] > profit
# 1 - 9 > 0 # => false
i += 1 # => 8
day # => 0
# iteration 7
if prices[i] - prices[day] > profit
# 10 - 17 > 0 # => false
i += 1 # => 9
day # => 1
# iteration 8
if prices[i] - prices[day] > profit
# nil - 3 > 0 # => NoMethodError
在第8次迭代,外環,導致發出出界錯誤的時訪問所述價格陣列prices[i]
,但仍與的(0...7)
的範圍這是後的設定的 第二環路內迭代第5次迭代,所以 它沒有達到你的while循環的escape子句/表達式 while i < prices.length
。
可能的解決方案:
你可以繼續你的工作的解決方案,或者您可以通過使用 另一個範圍爲外環
(1...prices.length).each do |i|
# ...
end
而不是內增加一個索引計數器變量簡化代碼while循環
i = 1
while i < prices.length
# ...
i +=1
end
看起來像這樣
def stock_picker prices
min_day , max_day , profit = 0 , 0 , 0
(1...prices.length).each do |i|
(0...i).each do |day|
if prices[i] - prices[day] > profit
min_day , max_day , profit = day , i , prices[i] - prices[day]
end
end
end
return "[#{min_day}, #{max_day}]"
end
prices = [17,3,6,9,15,8,6,1,10]
puts stock_picker prices
它會遍歷下面對天的,按您的要求
[i, day]
# => [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0],
# [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1],
# [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2],
# [4, 3], [5, 3], [6, 3], [7, 3], [8, 3],
# [5, 4], [6, 4], [7, 4], [8, 4],
# [6, 5], [7, 5], [8, 5],
# [7, 6], [8, 6],
# [8, 7]
UPDATE:
您也再次與Ruby Array combination
method
(0...prices.length).to_a.combination(2)
簡化它
要生成s AME天爲迭代的唯一且不可重複對在範圍暗示,這將是這樣的
def stock_picker prices
min_day , max_day , profit = 0 , 0 , 0
(0...prices.length).to_a.combination(2).each do |day, i|
if prices[i] - prices[day] > profit
min_day , max_day , profit = day , i , prices[i] - prices[day]
end
end
return "[#{min_day}, #{max_day}]"
end
prices = [17,3,6,9,15,8,6,1,10]
puts stock_picker prices
|day, i|
將訪問組合的陣列中日指數對陣列中的第一和第二變量,而重用您使用的現有變量名稱。
喜在迭代例子,你是怎麼算天數?不應該每次按照範圍(0 ... 1)迭代時+1。從我的理解是,在迭代0,一天應該是0,在迭代1,一天應該是1,迭代2天應該是2等等。我認爲我誤解了那裏的某些部分。 – roppo
重新運行您的原始代碼在遇到'nil'之前,我會獲得以下幾個'[i,day]':[1,0],[2,0],[3,1],[4,0], [5,1],[6,2],[7,3],[8,0],[9,1]'。 對於迭代0和迭代1,它是'0'兩次的原因是因爲使用了包容性與獨佔範圍;例如'(0..1).to_a#=> [0,1]'vs'(0 ... 1).to_a#=> [0]'。因此,範圍'(0 ... 1)'將運行一次,這是迭代0,並且對於範圍'(0 ... 2)',這是迭代1和2的兩次。 >使用'構造的範圍。 。從頭到尾包容性地運行。那些使用'...'創建的排除了最終值。 – sonna