Каков подходящий метод для получения суммы двух наибольших значений в массиве с использованием Ruby?Как суммировать наибольшие два элемента в массиве
Я знаю array.sort
и array.max
и inject(:+)
, но я не знаю, как их сочетать.
Каков подходящий метод для получения суммы двух наибольших значений в массиве с использованием Ruby?Как суммировать наибольшие два элемента в массиве
Я знаю array.sort
и array.max
и inject(:+)
, но я не знаю, как их сочетать.
[1,2,3,4].sort[-2..-1].inject(:+)
Если вы ищете более эффективное решение, вы будете лучше с этим один:
[1,2,3,4].inject([0, 0]) do |largest, el|
if largest[0] < el
largest[1] = largest[0]
largest[0] = el
elsif largest[1] < el
largest[1] = el
end
largest
end.inject(:+)
Если вы знакомы со сложностью алгоритма, чем вы можете увидеть, что первый из них является nlogn
до n^2
, в зависимости от алгоритма сортировки Ruby, где второе решение равно n
, когда оно проходит через массив один раз.
Я обновил свой ответ с более эффективным решением. –
«эффективный» не является хорошим словом, чтобы описать разницу. Первая короче, понятна и понятна, и работает примерно в 50 раз быстрее, чем вторая. Это также идиоматический Ruby при попытке выполнить эту задачу. –
В дополнение к точке @ theTinMan, асимптотические сравнения часто несущественны. Тебе нужно протестировать. В частности, когда один метод оптимизирован в C (например, 'sort'), а другой нет, первый часто бывает быстрее, иногда на милю. –
[9, 4, 5, 1].sort.last(2).sum
=> 14
Прохладный. Не знал о последствиях с аргументами. 'sum', хотя это метод Rails. Он задал вопрос как RoR, но спросил решение Ruby. Неясно, нужен ли ему ванильный раствор. –
Я добавил тесты для тестирования различных решений. См. Http://stackoverflow.com/a/38809082/128421 –
Ruby получит 'Enumerable # sum' в [версии 2.4] (http://www.blackbytes.info/ruby-version-changes/). –
Вы могли бы попробовать что-то вроде этого
array = [13, 2, 21, 36, 4, 9]
array.reverse.first(2).reduce(:+)
В этом методе мы обратной сортировки массива, который сортирует его от самого высокого до самого низкого. Это ставит наибольшие числа сначала в массиве. reduce
метод возвращает сумму этих чисел. В этом случае, сумма 36 и 21 57.
57
Поскольку это вопрос с Rails, 'sum' будет предпочтительнее, чем' reduce (: +) '. –
'array.reverse.first (2) .reduce (: +) # => 13'. Вы не сортируете массив вообще. Всегда хорошо проверять вашу работу. –
Я бы сильно благоприятствуют тем проще и быстрее:
array.max(2).reduce(:+)
Сортировка ненужно, достаточно для сканирования массива обновляющий макс -разрыв размера K. Используя Array#max(K)
, вы достигаете асимптотической сложности времени O (N x log (K)) по сравнению с O (N x log (N)) сортировки.
Отличное использование 'max'. –
Это всегда хорошо иметь несколько тестов, чтобы увидеть, что это самый быстрый способ сделать что-то:
require 'active_support/core_ext/enumerable'
require 'fruity'
ARRAY = (0..1000).to_a.shuffle
compare do
adriano { ARRAY.max(2).reduce(:+) }
mori { ARRAY.sort.last(2).sum }
edgars { ARRAY.sort[-2..-1].inject(:+) }
end
# >> Running each test 64 times. Test will take about 1 second.
# >> adriano is faster than edgars by 50.0% ± 10.0%
# >> edgars is similar to mori
Задавая это важно показать усилия к решению этой проблемы, в противном случае это выглядит, как вы хотите, чтобы мы написали код для вас. Прочитайте «[ask]», включая связанные страницы, и «[Сколько усилий ожидается от пользователей Stack Overflow?] (Http://meta.stackoverflow.com/q/261592/128421)». Также важно выбрать ответ, который решил проблему: http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work –