Создание функции, возвращающей разные массивы?

1

Я пытаюсь определить функцию, merge, которая при задании двух отсортированных массивов, содержащих числа, возвращает отсортированный массив чисел из обоих списков.

merge([ 4, 5, 6 ], [ 1, 2, 3, 4 ]) => [ 1, 2, 3, 4, 4, 5, 6 ]
merge([ 4 ], [ 2, 5, 8 ]) => [ 2, 4, 5, 8 ]
merge([ 1, 2, 6 ], []) => [ 1, 2, 6 ]

Это мой код:

function merge(arr1, arr2) {
  return arr1.concat(arr2).sort(arr1, arr2);
}

Хотя вывод верен, мне говорят - из моих исследований и его автоматизированных тестов - что этот код не в хорошем стиле. Он пишет:

Не обрабатывает два массива одинаковой длины.

Не обрабатывает более короткий первый массив.

Не обрабатывает более короткий второй массив.

Каким образом я могу написать этот код? Что мне делать лучше?

  • 0
    Когда я пробую ваш код, я получаю сообщение об ошибке в консоли, потому что аргумент sort() должен быть функцией, а не массивом. Вы уверены, что ваш вывод правильный?
  • 0
    Вы правы, это должна быть функция.
Теги:
arrays

4 ответа

4
Лучший ответ

Ваш код выглядит нормально, однако способ sort неправильный. Один из способов использования сортировки - предоставить функцию, которая сравнивает два значения в массиве и возвращает число (положительное или отрицательное), чтобы диктовать сортировку этих значений. Дополнительные сведения о сортировке см. В этой статье.

Рассмотрите следующие изменения в методе слияния:

function merge(arr1, arr2) {
  return arr1.concat(arr2).sort(function(valueA, valueB) { return valueA - valueB; );
}
3

Ответ Амадана обратил внимание на проблемы и указал, что это можно записать в O (n) времени. По сути, когда входы сортируются, алгоритм является шагом "слияния" в сортировке слияния. Это делается в линейном времени и работает очень простым и приятным образом: посмотрите на первый элемент каждого списка и возьмите меньший из двух, пока один или оба списка не будут исчерпаны. Затем привяжите все оставшиеся элементы к массиву результатов и верните его.

Другие ответы хороши и в хорошем стиле JS, но находятся в O (n log n) времени и полностью игнорируют, что массивы предварительно отсортированы без упоминания, что почти наверняка не является ответом, который запрашивает эта процедура.,

Здесь шаг слияния:

const merge = (a, b) => {
  const result = [];

  while (a.length && b.length) {
    result.push(a[0] < b[0] ? a.shift() : b.shift());
  }

  return result.concat(a).concat(b);
};

console.log(merge([ 4, 5, 6 ], [ 1, 2, 3, 4 ])); // => [ 1, 2, 3, 4, 4, 5, 6 ]
console.log(merge([ 4 ], [ 2, 5, 8 ])); // => [ 2, 4, 5, 8 ]
console.log(merge([ 1, 2, 6 ], [])); // => [ 1, 2, 6 ]

Это также можно сделать с помощью индексов, которые сохраняют исходные массивы и быстрее, но немного уродливее.

Вот эталон в JSPerf.

Изображение 174551

3

Другие ответы уже дают вам буквальный ответ о том, как правильно сделать код. Однако, возможно, это не так. Функция, которую вы описали, используется при построении "сортировки слияния", очень важного алгоритма сортировки, основным преимуществом которой является то, что ему нужно только один раз прочитать входные списки, последовательно, что приведет к сложности O (N) за проход; это позволяет даже сортировать вещи, которые не могут вписаться в память. Ваш код этого не делает - он использует sort, которая является O (N log (N)) при каждом вызове вашей функции, и не использует тот факт, что оба входа уже предварительно отсортированы (что является ключевое требование для сортировки слияния).

Алгоритм сортировки слияния возьмет первый элемент из обоих списков, а затем добавит меньший. Затем он сравнивает следующий элемент из этого списка с другим первым элементом списка и снова берет меньший. Повторяйте до тех пор, пока один список не будет исчерпан, а затем добавьте оставшийся список выживших. (Вы можете найти более исчерпывающее объяснение сортировки слияния на странице Википедии).

  • 1
    Отличный ответ - хорошее понимание
  • 0
    Все верно, но если вы не имеете дело с большими наборами данных, а производительность критична, использование встроенных функций, вероятно, будет достаточно хорошо.
Показать ещё 2 комментария
1

Просто concat массивы и вернитесь после применения простой функции sort:

console.log(merge([4, 5, 6], [1, 2, 3, 4])); //[ 1, 2, 3, 4, 4, 5, 6 ]

console.log(merge([4], [2, 5, 8])); //[ 2, 4, 5, 8 ]

console.log(merge([1, 2, 6], [])); //[ 1, 2, 6] 


function merge(a, b) {
  return a.concat(b).sort((a, b) => a - b);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню