Алгоритм сбора наименьших чисел

Я ищу алгоритм (или код PHP, я полагаю), чтобы получить 10 наименьших чисел из группы чисел. Я думал создать массив из десяти элементов, проверяя, не меньше ли текущее число, чем одно из чисел в массиве, и, если да, найти наибольшее число в массиве и заменить его текущим числом.

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

Дубликат stackoverflow.com/questions/350519/…

ShreevatsaR 30.12.2008 05:16

Хотя это в PHP, а не в Python.

lpfavreau 30.12.2008 06:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
951
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Отсортируйте массив и используйте десять первых / последних записей.

Честно говоря: сортировка массива с тысячей записей стоит меньше времени, чем вам нужно моргнуть.

Нильс, еще приятнее встретить тебя здесь. :)

Bombe 30.12.2008 01:55

+1, если бы вы могли придумать способ сделать это быстрее, чем быстрая сортировка, то вы бы не задавали этот вопрос: D

Kent Fredric 30.12.2008 03:09

С точки зрения большого O, лучше выполнить один проход для поиска 10 наименьших записей (O (n)), чем обычную всеобъемлющую сортировку (O (n log n)). Но если у вас небольшой набор данных и ваш язык быстрый (я никогда не использовал PHP, поэтому не могу комментировать), это не имеет значения. Итак, +1.

paxdiablo 30.12.2008 03:52

Откуда у вас эта группа цифр?

Если ваш список чисел уже находится в массиве, вы можете просто выполнить Сортировать(), а затем array_slice (), чтобы получить первые 10.

Наивный подход - просто отсортировать ввод. Вероятно, это достаточно быстро, поэтому просто попробуйте и профилируйте его, прежде чем делать что-либо более сложное.

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

output[0-9] = input[0-9];
sort(output);
for i=10..n-1
  if input[i] < output[9]
    insert(input[i])

где insert (x) найдет нужное место (бинарный поиск) и выполнит соответствующий сдвиг.

А если серьезно, сначала попробуйте наивный подход.

-1. Наивные подходы могут работать для всех ваших тестов, а затем однажды случайно погибнуть в реальном мире. Оставьте фантазии на усмотрение экспертов. Используйте то, что существует, если вы не знаете, что можете добиться большего.

Kent Fredric 30.12.2008 03:10

Похоже, вам нужны более репрезентативные тесты. И вы неправильно прочитали, «Наивный подход» был первой половиной, что совпадает с ответом, за который вы проголосовали. Вы хотели не согласиться с «потенциально более быстрым подходом».

Andrew Coleson 30.12.2008 03:15

@Kent, наивный подход было к сортировке PHP, вы, кажется, неправильно поняли. Если однажды PHP-сортировка умрет в реальном мире, у многих будут проблемы :-).

paxdiablo 30.12.2008 03:54

$ бит-> флип (); $ self-> fail (); do {appology («Я был наивным»); }

Kent Fredric 30.12.2008 04:09

Без проблем. Рекомендация чего-то подверженного ошибкам в качестве альтернативы наивным решениям и решениям из Википедии, вероятно, в любом случае была менее полезной. :)

Andrew Coleson 30.12.2008 04:16
Ответ принят как подходящий

То, что вы ищете, называется алгоритм выбора. На странице Википедии по этой теме есть несколько подразделов в разделе выбор наименьшего или наибольшего элемента k. Когда список достаточно велик, вы можете бить время, необходимое для наивного алгоритма «отсортировать весь список и выбрать первые 10».

Чтобы быть конкретным, разделы «Оптимизированные алгоритмы сортировки» предлагают производительность O (n + k * lg (k)), если нужно отсортировать 10 самых низких 10. Если их не нужно сортировать между собой, возможно O (n)!

Andrew Coleson 30.12.2008 03:29

Я не имею большого значения для небольшого массива, но по мере того, как он становится больше, быстрый и простой способ увеличить скорость обработки - воспользоваться преимуществами индексации ключей массива, которая составляет 1 миллиард. строки будут использовать около 40% времени. Пример:

// sorting array values

$numbers = array();
for($i = 0; $i < 1000000; ++$i)
{
    $numbers[$i] = rand(1, 999999);
}

$start = microtime(true);
sort($numbers);
$res = array_slice($numbers, 0, 10, true);
echo microtime(true) - $start . "\n";
// 2.6612658500671
print_r($res);

unset($numbers, $res, $start);


// sorting array keys

$numbers = array();
for($i = 0; $i < 1000000; ++$i)
{
    $numbers[rand(1, 999999)] = $i;
}

$start = microtime(true);
ksort($numbers);
$res = array_keys(array_slice($numbers, 0, 10, true));
echo microtime(true) - $start . "\n";
// 0.9651210308075
print_r($res);

Но если данные массива взяты из базы данных, скорее всего, быстрее всего будет просто отсортировать их там:

SELECT number_column FROM table_with_numbers ORDER BY number_column LIMIT 10

Создайте отсортированный набор (TreeSet в Java, я не знаю о PHP) и добавьте первые 10 чисел. Теперь переберите остальные числа. Переберите все свои числа, добавьте новое, затем удалите самое большое число из набора.

Этот алгоритм O (n), если n >> 10.

Я бы использовал куча с 10 элементами и самым большим числом в корне дерева. Затем начните с начала списка чисел:

  • Если в куче меньше 10 элементов: добавьте номер в список
  • В противном случае, если число меньше наибольшего числа в куче, удалите наибольшее число в куче, а затем добавьте текущий номер в список.
  • В противном случае игнорируйте это.

В итоге вы получите 10 наименьших чисел в куче. Если вы используете массив в качестве структуры данных кучи, вы можете просто использовать массив напрямую.

(в качестве альтернативы: вы можете вырезать первые 10 элементов и сложить их в кучу вместо использования первого шага выше, который будет немного быстрее).

Однако, как отмечали другие люди, для 1000 элементов просто отсортируйте список и возьмите первые 10 элементов.

Другие вопросы по теме