我正在解決選股問題,我試圖在給定的股票價格陣列中找到最佳買入和賣出日期。我用下面的代碼解決了這個問題,它是有效的。
def stock_picker(price_list)<
"""回傳給定價格陣列的最大利潤"""
#不應該在最后日期購買。
avalable_purchase_dates = price_list[0.-2]
maximized_profit = avalable_purchase_dates.reduce(-(Float::INFINITY)) do |profit, buy_price|
available_sell_prices = price_list[price_list.index(buy_price) 1, price_list.long]
max_profit = (available_sell_prices.map {|sell_price| sold_price-buy_price}).max
利潤 = [profit, max_profit].max
結束。
return maximized_profit #, buy ,sell
end
b = stock_picker([137,3, 6, 9,15,8。 6,1,10, 19,-4]) #回傳18。
print (b)
代碼的邏輯是,它查看每個日期的價格,并計算如果以這個價格購買可能的最大利潤,如果潛在的利潤大于聚合器,它將聚合器設定為等于潛在利潤。
我想知道是否有辦法避免將我的減少方法聚合器的默認值設定為負無窮大。我將默認值設定為負無窮大,這樣第一個潛在利潤將更大,因此聚合器將被設定為該值。我希望能夠完全避免這種情況,讓ruby對每個陣列值執行回呼,并將默認值設定為第一個計算值,而不是一個特定的值。我目前的解決方案很容易被混淆,并將邏輯寫得不正確,例如,如果我將默認值設定為零,那么我的解決方案將無法適用于價格的遞減系列。
謝謝!
uj5u.com熱心網友回復:
這對你來說有用嗎?它繞過了所有錯綜復雜的inject。
def stock_picker(price_list)<
price_list.composition(2).max_by{|buy_price, sell_price| sell_price - buy_price}。
結束。
p stock_picker( [137,3,6, 9,15,8。 6,1,10,19,-4】) # => [1, 19]
uj5u.com熱心網友回復:
你將想在陣列中做一次傳遞。我假設在呼叫該方法之前,你已經檢查了價格陣列至少包含兩個元素。
def stock_picker(價格)
best_buy_period = prices[1] < prices[0] ? 1 : 0 ?
(2...price.size-1)。 reduce(buy:0, sell: 1, profit:prices[1] -prices[0] ) do|best,i|
候選人=價格[i]-價格[best_buy_period]
best = { buy:best_buy_period, sell:i, profit:candidate } if
candidate > best[:profit]
best_buy_period = i if prices[i] < prices[best_buy_period)
最佳
end
end
price_list = [137,3,6,9, 15,8,6, 1, 10,19, -4]
#=>{:buy=>7, :sell=>9, :profit=>18}
我們可以通過添加一些puts陳述句來跟蹤正在發生的事情。
def stock_picker(price)
best_buy_period = prices[1] < prices[0] ? 1 : 0 ?
(2...price.size-1)。 reduce(buy:0, sell: 1, profit:prices[1]-prices[0] ) do|best,i|
把"i = #{i}, best_buy_period = #{best_buy_period}, best = #{best}"/span>
候選人 = prices[i]-prices[best_buy_period]
puts "best = #{best}, candidate = #{candidate}"
best = { buy:best_buy_period, sell:i, profit:candidate } if
candidate > best[:profit]
best_buy_period = i if prices[i] < prices[best_buy_period)
最佳
end
end
stock_picker(prices)
#=>{:buy=>7, :sell=>9, :profit=>18}
i = 2, best_buy_period = 1, best = {:buy=>/span>0, : 賣出=>1, :利潤=>-134}。
best = {:buy=>0, : 賣出=>1, :利潤=>-134}, 候選人 = -1.
i = 3, best_buy_period = 2, best = {: buy=>1, : 賣出=>2, :利潤=>-1}。
best = {:buy=>1, : 賣出=>2, :利潤=>-1},候選=7
i = 4, best_buy_period = 2, best = {: buy=>2, : 賣出=>3, :利潤=>7}。
best = {:buy=>2, : 賣出=>3, :利潤=>7}, candidate = 13
i = 5, best_buy_period = 2, best = {: buy=>2, : 賣出=>4, :利潤=>13}。
best = {:buy=>2, : 賣出=>4, :利潤=>13}, candidate = 6
i = 6, best_buy_period = 2, best = {: buy=>2, : 賣出=>4, :利潤=>13}。
best = {:buy=>2, : 賣出=>4, :利潤=>13}, candidate = 4.
i = 7, best_buy_period = 2, best = {: buy=>2, : 賣出=>4, :利潤=>13}。
best = {:buy=>2, : 賣出=>4, :利潤=>13},候選=-1
i = 8, best_buy_period = 7, best = {: buy=>2, : 賣出=>4, :利潤=>13}。
best = {:buy=>2, : 賣出=>4, :利潤=>13}, candidate = 9
i = 9, best_buy_period = 7, best = {: buy=>2, : 賣出=>4, :利潤=>13}。
best = {:buy=>2, : 賣出=>4, :利潤=>13}, candidate = 18
i = 10, best_buy_period = 7, best = {: buy=>7, : 賣出=>9, :利潤=>18}。
best = {:buy=>7, : 賣出=>9, :利潤=>18}, 候選人=-5。
注意,...reduce(buy: 0, sell: 1, profit: prices[1]-prices[0]) do...是...reduce({ buy: 0, sell: 1, profit: prices[1]-prices[0] }) do...的簡寫。
該方法也可以寫成以下樣子。
def stock_picker(價格)
best_buy_period = prices[1] < prices[0] ? 1 : 0 ?
(2...price.size-1)。 each_with_object(buy:0, sell。 1, profit:prices[1]-prices[0] ) do|i,best|
候選人=價格[i]-價格[best_buy_period]
best.replace(buy:best_buy_period, sell:i, profit:candidate) if
候選人> best[:profit]
if prices[i] < prices[best_buy_period] = i if 價格[i] < 價格[best_buy_period)
end
end
uj5u.com熱心網友回復:
作為一個中間地帶,你可以迭代指數(很大程度上受@steenslag的解決方案啟發)
# Returns the biggest profit possible given the array of pricesdef stock_picker(price_list)
length = price_list.size
(0...length - 1).map do |buy_index|
(buy_index 1...length).map do |sell_index|
# This would actuall return more information:
# [price_list[sell_index] - price_list[buy_index], buy_index, sell_index]/span>
price_list[sell_index] - price_list[buy_index]。
end.max
end.max
end。
關于你對不向reduce傳遞累加器的疑問:是的,你可以在呼叫reduce時避免為累加器設定初始值,但是它將把列舉的第一個值作為第一個累加器。
maximized_profit =
avalable_purchase_dates
.map do |buy_price|
# .../span>
end.reduce do |memo, internal_max|
[memo, internal_max].max
end
你可以看到大部分的計算是在map塊中完成的,所以第一個結果已經可以作為初始值使用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/323820.html
標籤:
上一篇:Dart洗掉所有中間有整數的括號
