Разделить четные и нечетные числа в заданном массиве

08.09.2021

Я не хочу использовать для этого другой массив, поэтому пошел с логикой подкачки. Есть ли шансы на улучшение / оптимизацию этого кода?

Какого минимума пространства и времени мы можем достичь для этой задачи?

3 ответа 3

Я сильно сомневаюсь, что ваша программа делает именно это:

AFAIK выход будет

т.е. элементы переупорядочиваются из-за перестановки. Но это нормально в зависимости от того, что требуется.

Это не функция, это метод. И назвать что-то дажеOddMethod было бы не лучше, поскольку в нем нет информации. что-то вроде evenOddSegregator звучит лучше, но имена методов должны быть глаголами. Так может быть segregateEvenOdd?

Ненавижу повторяющиеся условия. Как насчет

Это не совсем то же самое, но это не имеет значения.

Это неправильное название (и тоже тип). В этом методе нет ничего четного и странного.

Есть ли шансы на улучшение / оптимизацию этого кода?

Думаю, ваш код оптимален, за исключением этой низкоуровневой оптимизации: вместо (x% 2) используйте x & 1; он намного быстрее, лучше работает с отрицательными числами и т. д. Но JIT тоже знает этот трюк, и от этого не так много пользы.

Непроверенное, глупое, но забавное решение:

Компаратор утверждает, что четное число меньше нечетного, и всю работу выполняет sort. Он даже стабилен, то есть он не меняет порядок того, что ему не нужно, и выдает результат из вашего примера. Guava's Ints адаптирует массив как List .

Интерфейс

Было бы полезно добавить в JavaDoc заявление об отказеот ответственности, что порядок элементов нестабилен, особенно с учетом того, что приведенные вами примеры предполагают, что он может быть стабильным.

Называтьфункцию чем-тоFunction очень излишне. Я считаю это крайней формой венгерской системы обозначений. Я предлагаю evenOddPartition в качестве имени для этой функции.

А что хорошего в такой функции разделения? Хотя формулировка задачи не требует этого, я думаю, что было бы неплохо, если бы функция сообщила вам, где находится четно-нечетная граница.Поэтому я предлагаю, чтобы он возвращал int, который указывает количество четных элементов (или, как вариант, индекс первого нечетного элемента, если он есть).

Наконец, я должен отметить, что вас попросили «написать функцию», которая принимает массив, а не «написать программу», которая выполняет эту задачу. Я думаю, это означает, что функция, которую вы пишете, должна быть публичной, а не частной.

Эффективность

Ваша стратегия состоит в том, чтобы увеличивать индекс leftSide и уменьшать индекс rightSide, пока они не встретятся. Общее количество изменений индекса - это, конечно, data.length, поэтому ваш алгоритм - O ( n ), где n - размер массива. Очевидно, что эту границу нельзя улучшить, поскольку невозможно выполнить эту задачу, не проверив каждый элемент хотя бы один раз.

Однако некоторые микрооптимизации все же возможны. Чтобы добраться до ветки else… if… leftSide ++, вам потребуется выполнить одну проверку границ индекса и трипроверки по модулю 2, что является довольно избыточным. В идеале каждая leftSide ++ должна включать только одну проверку границ и одну проверку четности.

Поэтому я предлагаю такое решение:

Я решил просто написать подкачку встроенной, а не в качестве вспомогательной функции. (Кстати, почему вы написали swap как swapp?) Возможно, разбиение кода на вспомогательную функцию помогает читабельности, и JIT должна иметь возможность выяснить, что ваша частная статическая вспомогательная функция может быть встроена, поэтому в в долгосрочной перспективе у вас нет накладных расходов на вызов функций. Тем не менее, хлопот можно избежать, просто написав встроенный код. Я думаю, что присвоение имени временной переменной подкачки (лучше, чем temp) дает достаточно визуального намека на то, что удобочитаемость не страдает.

Сергей Иващенко

08.09.2021

Подписывайтесь на наши социальные сети!