【问题标题】:I'm trying to do a stock picker method on Ruby but i have some issue in my code我正在尝试在 Ruby 上做一个股票选择器方法,但我的代码中有一些问题
【发布时间】:2019-08-14 16:33:36
【问题描述】:

我正在尝试做一种选股方法,它可以接收一系列股票价格,每个假设日都有一个。它应该返回一对代表最佳买入日和最佳卖出日的日期。天数从 0 开始。

def stock_picker stocks
  pair = []

  if stocks.size < 2
    return "Please enter an array with a valid number of stocks"
  else
    buy_day = 0
    sell_day = 0
    profit = 0

    stocks.each_with_index do |buy, index|
      i = index
      while (i < stocks[index..-1].size)
        if ((buy - stocks[i]) > profit)
          profit = buy - stocks[i]
          buy_day = stocks.index(buy)
          sell_day = i
        end
        i+= 1
      end

    end
    pair = [buy_day,sell_day]
    return pair.inspect
  end
end

stock_picker([17,3,6,9,15,8,6,1,10])

它应该返回 [1,4] 而不是 [0,7]

【问题讨论】:

  • 看起来您的解决方案正在弄乱一个标志,因为您收到了最坏场景的正确值。 旁注:你不需要在方法的最后一行使用return

标签: ruby


【解决方案1】:

您可以在 stock_prices 数组中循环选择具有最大正差的日子。您的 while 条件需要更改。

#steps
#sets value of biggest_profit to 0(biggest_loss if looking for loss)
#sets most_profitable_days to [nil,nil]
#loops through array
#takes buy day
#loops through remainder of array
#if current day-first day>biggest_profit (first_day-current_day for loss)
#make >= for shortest holding period
#reassign biggest_profit
#most_profitable_days.first=buy_day, most_profitable_days.last=sell_day
#sell_day & buy_day are values of indices

#tests
#must accept only array
#must return array
#must return correct array

def stock_picker(arr)

    #checks to make sure array inputs only are given
    raise 'Only arrays allowed' unless arr.instance_of?(Array)

    #sets value of biggest_profit to 0(biggest_loss if looking for loss)
    biggest_profit=0

    #sets most_profitable_days to [nil,nil]
    most_profitable_days=[nil,nil]

    #loops through array
    arr.each_with_index do |starting_price, buy_day|

        #takes buy day
        arr.each_with_index do |final_price,sell_day|

            #loops through remainder of array
            next if sell_day<=buy_day

            #if current day-first day>biggest_profit (first_day-current_day for loss)
            #make '>=' for shortest holding period
            if final_price-starting_price>=biggest_profit

              #reassign biggest_profit
              biggest_profit=final_price-starting_price

              #most_profitable_days.first=buy_day, 
              most_profitable_days[0]=buy_day#+1 #to make it more user friendly

              #most_profitable_days.last=sell_day
              most_profitable_days[-1]=sell_day#+1 #to make it more user friendly
            end
        end
    end
    
  #return most_profitable_days
  most_profitable_days
end
p stock_picker([3,2,5,4,12,3]) #[1,4]

【讨论】:

    【解决方案2】:

    另一种选择是在迭代数组时对数组进行切片以找到最佳利润:

    res = ary.each_with_index.with_object([]) do |(buy_val, i), res|
      highest_val = ary[i..].max
      highest_idx = ary[i..].each_with_index.max[1] + i
      res << [highest_val - buy_val, i, highest_idx]
    end.max_by(&:first)
    
    #=> [12, 1, 4]
    

    其中12 是利润,1 是买入指数,4 是卖出指数。


    要了解它是如何工作的,请运行这个扩展版本,它比任何书面解释都更有价值:
    res = []
    ary.each_with_index do |buy_val, i|
      p buy_val
      p ary[i..]
      p highest_val = ary[i..].max
      p highest_idx = ary[i..].each_with_index.max[1] + i
      res << [highest_val - buy_val, i, highest_idx]
      p '----'
    end
    
    res #=> [[0, 0, 0], [12, 1, 4], [9, 2, 4], [6, 3, 4], [0, 4, 4], [2, 5, 8], [4, 6, 8], [9, 7, 8], [0, 8, 8]]
    

    来自 Ruby 标准库,我使用了 Enumerable#each_with_indexEnumerable#each_with_objectEnumerable#maxEnumerable#max_by


    为了获得最大值的索引,我好心从 Chuck (https://stackoverflow.com/a/2149874) 那里偷了,谢谢和 +1。我没有寻找更好的选择。

    根据链接帖子中 Cary Swoveland 的评论:

    [..] a.index(a.max) 将返回第一个和 a.each_with_index.max[1] 将返回最后一个 [..] 的索引

    所以,也许您想使用第一个选项来缩短买卖之间的时间。

    【讨论】:

      【解决方案3】:

      使用Array#combination:

      stocks.
          each_with_index.
          to_a.
          combination(2).
          select { |(_, idx1), (_, idx2)| idx2 > idx1 }.
          reduce([-1, [-1, -1]]) do |(val, acc), ((v1, idx1), (v2, idx2))|
        val < v2 - v1 ? [v2 - v1, [idx1, idx2]] : [val, acc]
      end
      #⇒ [ 12, [1, 4] ]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-01
        • 2020-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多