这是在哪里发生的?
你的错误
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,
它不响应减号- 运算符。
为什么会这样?
你是循环中的循环
(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 中的每个值
数组 once 对 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] 访问价格数组,但仍在
在第 5 次迭代后设置的范围为 (0...7) 的第二个循环,所以
它没有到达您的 while 循环的转义子句/表达式
while i < prices.length.
可能的解决方案:
您可以保留您的工作解决方案,或者您可以通过使用来简化您的代码
另一个 Range 作为外循环
(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]
更新:
您还可以使用Ruby Array combination method 再次简化它
(0...prices.length).to_a.combination(2)
生成与迭代隐含的 Ranges 相同的唯一且不重复的天对,如下所示
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| 将访问组合数组中日期索引对数组中的第一个和第二个变量,同时重用您已使用的现有变量名称。