Как найти индексы макс n элементов в массиве в устойчивом порядке - PullRequest
0 голосов
/ 16 мая 2018

У меня есть номер и массив:

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

Я хочу найти индексы, соответствующие максимальным n элементам a в обратном порядке размера элемента и в стабильном порядке, когда размеры элемента равны. Ожидаемый результат:

[5, 3, 4, 2]

Этот код:

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

дает правильные индексы, но меняет порядок.

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

Код

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 не обязательно должны быть числовыми, просто сопоставимыми.

0 голосов
/ 17 мая 2018

@ 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 , чтобы остановить каждый метод, сохраняющий последнее значение i что соответствует положению максимального значения в массиве.Имейте в виду, что значение i отличается одной из естественных позиций в массиве, и это потому, что в массивах первый элемент равен 0, а не 1.

I break каждый , потому что нет необходимости постоянно проверять все остальные значения массива после того, как мы нашли позицию значения.

0 голосов
/ 17 мая 2018

Вы можете предоставить блок для 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 <=> 3 #=> -1 -1 означает, что это значение меньше, поэтому оно будет помещено после 3

Также подробно остановимся на ответе @ CarySwoveland (о котором я немного завидую, о котором я не задумывался), поскольку вам нужно только вернуть индексы, которые мы могли бы реализовать следующим образом, без дополнительного map

a.each_index.max_by(n) { |x| [a[x],-x] }
#=> [5,3,4,2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...