def stock_picker prices
min_day , max_day , profit = 0 , 0 , 0
i = 1
while i < prices.length
(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 += 1
end
return "[#{min_day}, #{max_day}]"
end
prices = [17,3,6,9,15,8,6,1,10]
puts stock_picker prices
我的目标是实施一种方法#stock_picker,它接受一系列股票价格,每个假设日一个。它应该返回一天代表最佳购买日和最佳销售日。天数从0开始。
我的问题是,如果我删除第11行并将其写在第9行,为什么这段代码不起作用。然后会导致错误如下:
**PS C:\Users\dlim\mystuff> ruby stockpicker.rb
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>'
答案 0 :(得分:1)
您基本上是在尝试重写combination
和max_by
:
prices = [17, 3, 6, 9, 15, 8, 6, 1, 10]
days = (0...prices.size).to_a
p days.combination(2).max_by { |day1, day2| prices[day2] - prices[day1] }
# => [1,4]
如果您想要两天和相应的价格:
[17,3,6,9,15,8,6,1,10].each.with_index.to_a.
combination(2).max_by{|(buy, day1), (sell, day2)|
sell-buy
}
# => [[3, 1], [15, 4]]
答案 1 :(得分:0)
这种情况发生在哪里?
您的错误
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
中的每个值
数组一次,对应day
内部数组中的下一个prices
值
将只包含prices
的前三个值(表示值为
prices
数组的结尾,例如1
和10
永远不会被比较
另一个); e.g。
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循环的转义子句/表达式
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)
生成相同的唯一且不重复的天数,以迭代隐含的范围,这看起来像这样
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|
将访问组合数组中日期索引对数组中的第一个和第二个变量,同时重用您已使用的现有变量名称。