array.index(y)没有在Ruby中给出预期的结果

时间:2014-07-22 18:47:11

标签: ruby

由于某种原因,price.index(y)和x给了我奇怪的答案

def stockpicker prices
    profits, buyday, sellday = 0, 0, 0

    i=0
    while i <= prices.length
        y = i + 1
        while y <= prices.length
            if prices[y].to_i - prices[i].to_i > profits
                profits = prices[y].to_i - prices[i].to_i
                sellday = prices.index(y).to_i
                buyday = prices.index(i).to_i
            end
            y += 1
        end
        i += 1
    end

    print "Profits are #{profits} if you buy on #{buyday} and sell on #{sellday}"

end

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

=&gt;如果您在8买入并在0

卖出,则利润为13

为什么不提供正确的索引位置?我真的不知道8和0来自哪里

3 个答案:

答案 0 :(得分:1)

假设你想要这个输出:

Profits are 12 if you buy on 1 and sell on 4

然后你应该将sellday / buyday设置为当前索引值:

sellday = y
buyday = i

使用sellday = prices.index(y).to_i,您说“给我数组中项目的索引,其中为4”。这导致nilnil.to_i将始终为您提供0

答案 1 :(得分:0)

现在您的问题已经得到解答,让我们看看如何以更加Rubylike的方式编写代码。有很多方法可以做到这一点。这是一个。

<强>代码

def stockpicker(prices)
  a = Array.new(prices.size) { |i|
        Array.new(prices.size) { |j|
          (j > i) ? prices[j]-prices[i] : -Float::INFINITY } }.flatten
  max_profit = a.max
  bd, sd = a.index(max_profit).divmod(prices.size)
  print "Profits are #{max_profit} if you buy on #{bd} and sell on #{sd}"
end

示例

prices = [17,3,6,9,15,8,6,9,1]
stockpicker(prices)
  #=> Profits are 12 if you buy on 1 and sell on 4

<强>解释

对于上面给出的例子:

a = Array.new(prices.size) { |i|
      Array.new(prices.size) { |j| 
        (j >= i) ? prices[j]-prices[i] : -Float::INFINITY } }
      #=> [[0, -14, -11, -8, -2, -9, -11, -8, -16],
      #    [-Infinity, 0, 3, 6, 12, 5, 3, 6, -2],
      #    [-Infinity, -Infinity, 0, 3, 9, 2, 0, 3, -5],
      #    [-Infinity, -Infinity, -Infinity, 0, 6, -1, -3, 0, -8],
      #    [-Infinity, -Infinity, -Infinity, -Infinity, 0, -7, -9, -6, -14],
      #    [-Infinity, -Infinity, -Infinity, -Infinity, -Infinity, 0, -2, 1, -7],
      #    [-Infinity, -Infinity, -Infinity, -Infinity, -Infinity, -Infinity,
      #       0, 3, -5],
      #    [-Infinity, -Infinity, -Infinity, -Infinity, -Infinity, -Infinity,
      #       -Infinity, 0, -8],
      #    [-Infinity, -Infinity, -Infinity, -Infinity, -Infinity, -Infinity,
      #       -Infinity, -Infinity, 0]]

此数组的行i,列j中的条目等于股票在日偏移量i上购买并在当天出售j时的利润。例如,考虑行(偏移)1,它对应于日偏移1上的股票购买:

      [-Infinity, 0, 3, 6, 12, 5, 3, 6, -2],

如果在j天购买的股票在抵消日1出售,则j列会获得利润。例如,如果在第4天出售,则利润为12.请注意,当卖出日在买入日之前时,我们指定负无穷大的利润。

接下来,展平这个数组:

b = a.flatten
  #=> [0, -14, -11, -8, -2, -9, -11, -8, -16,
  #    -Infinity, 0, 3, 6, 12, 5, 3, 6, -2,
  #    -Infinity, -Infinity, 0, 3, 9, 2, 0, 3, -5,
  #    -Infinity, -Infinity, -Infinity, 0, 6, -1, -3, 0, -8,
  #    -Infinity, -Infinity, -Infinity, -Infinity, 0, -7, -9, -6, -14,
  #    -Infinity, -Infinity, -Infinity, -Infinity, -Infinity, 0, -2, 1, -7,
  #    -Infinity, -Infinity, -Infinity, -Infinity, -Infinity, -Infinity, 0,
  #      3, -5,
  #    -Infinity, -Infinity, -Infinity, -Infinity, -Infinity, -Infinity,
  #    -Infinity, 0, -8,
  #    -Infinity, -Infinity, -Infinity, -Infinity, -Infinity, -Infinity,
  #    -Infinity, -Infinity, 0]

确定最大利润:

max_profit = b.max
  #=> 12

现在我们需要在展平数组中找到12的索引(如果有多个12,则获取第一个的索引):

c = b.index(max_profit)
  #=> b.index(12) => 13

然后使用Fixnum#divmod将此偏移量转换为unflattened数组中的行和列:

bd, sd = c.divmod(prices.size)
  #=> c.divmod(9) => [1, 4] => bd = 1, sd = 4

答案 2 :(得分:0)

以下是使用matrix操作的另一种方式:

def stockpicker(prices)
  m = Matrix.build(prices.size){ |x,y| prices[y] - prices[x]}
  max = m.each(:upper).max
  bd,sd = m.index(max, :upper)
  puts "Profits are #{max} if you buy on #{bd} and sell on #{sd}"
end

示例运行:

prices = [17,3,6,9,15,8,6,9,1]
stockpicker(prices)
#=> Profits are 12 if you buy on 1 and sell on 4

说明: 这构建了一个方形矩阵,每个价格从每个价格中减去。由于您只想从较早的日期中减去后几天,因此您只需要矩阵的上三角形(因此:upper)。有内置的Matrix函数来获取最大值及其索引。