【问题标题】:How to find indices of max n elements in array in stable order如何以稳定的顺序查找数组中最大 n 个元素的索引
【发布时间】:2018-05-16 20:29:45
【问题描述】:

我有一个数字和一个数组:

n = 4
a = [0, 1, 2, 3, 3, 4]

我想找到与a 的最大n 元素相对应的索引,以元素大小的相反顺序,并且在元素大小相等时以稳定的顺序。预期的输出是:

[5, 3, 4, 2]

这段代码:

a.each_with_index.max(n).map(&:last) 
# => [5, 4, 3, 2]

给出正确的索引,但改变顺序。

【问题讨论】:

  • 你的例子不是很好。您在数组中提供的元素很容易与索引混淆。它们看起来太相似了。

标签: arrays ruby


【解决方案1】:

代码

def max_with_order(arr, n)
   arr.each_with_index.max_by(n) { |x,i| [x,-i] }.map(&:last)
end

示例

a = [0,1,2,3,3,4]

max_with_order(a, 1)  #=> [5]
max_with_order(a, 2)  #=> [5, 3]
max_with_order(a, 3)  #=> [5, 3, 4]
max_with_order(a, 4)  #=> [5, 3, 4, 2]
max_with_order(a, 5)  #=> [5, 3, 4, 2, 1]
max_with_order(a, 6)  #=> [5, 3, 4, 2, 1, 0]

说明

n = 3的步骤如下。

b = a.each_with_index
  #=> #<Enumerator: [0, 1, 2, 3, 3, 4]:each_with_index>

我们可以将b 转换为一个数组,以查看它将生成并传递给块的(六个)值。

b.to_a                
  #=> [[0, 0], [1, 1], [2, 2], [3, 3], [3, 4], [4, 5]]

继续,

c = b.max_by(n) { |x,i| [x,-i] }
  #=> [[4, 5], [3, 3], [3, 4]]
c.map(&:last)
  #=> [5, 3, 4]

请注意,arr 的元素不必是数字,只需可比较。

【讨论】:

  • 美丽。正是我想出的答案。
  • 虽然我赞赏你的,总是彻底的回答,你的原始实现仍然在 Continuing 部分中引用,但新的实现(顺便说一句更好)不再使用min_by
【解决方案2】:

您可以向max 提供一个块以使确定更具体,就像这样

a.each_with_index.max(n) do |a,b| 
  if a[0] == b[0] # the numbers are the same
    b[1] <=> a[1] # compare the indexes in reverse
  else
    a[0] <=> b[0] # compare the numbers themselves
  end
end.map(&:last) 
#=> [5,3,4,2]

max 块期望类似的响应,例如-1,0,1 所以在这种情况下,我们只是说如果数字相同,则以相反的顺序比较索引,例如4 &lt;=&gt; 3 #=&gt; -1 -1 表示该值较小,因此将放在 3 之后

还要扩展@CarySwoveland 的答案(我有点嫉妒我没想到),因为您只关心返回我们可以在没有辅助map 的情况下实现的索引

a.each_index.max_by(n) { |x| [a[x],-x] }
#=> [5,3,4,2]

【讨论】:

  • @CarySwoveland 我受到了启发
【解决方案3】:

@compsy 你写的没有改变顺序,所以它会是:

a = [0,1,2,3,3,4]
n = a.max
i = 0
a.each do |x|
  break if x == n
  i += 1
end

我使用变量i作为索引,当x(这是被分析的值)等于n我们使用break 停止 each 方法,保存 i 的最后一个值,该值对应于数组中最大值的位置。请注意,i 的值与数组中的一个自然位置不同,这是因为数组中的第一个元素是 0 而不是 1。

break each 因为在我们找到值的位置后,不需要继续检查数组的所有其他值。

【讨论】:

  • 这实际上并没有做任何事情,除了可能改变i的值,取决于a中值的顺序,返回值将是[0,1,2,3,3,4],因为each迭代完成后将返回Enumerable
猜你喜欢
  • 2021-11-07
  • 1970-01-01
  • 2021-06-20
  • 2021-10-13
  • 2019-05-31
  • 2016-10-27
  • 1970-01-01
  • 2013-01-31
  • 2018-10-17
相关资源
最近更新 更多