Я знаю, что в ответе используется медиана медиан, но может ли кто-нибудь объяснить, как это сделать?
Как найти медиану большого количества целых чисел (они не помещаются в памяти)
comment
Здесь есть несколько тем на SO: Тема 1, Тема 2. И есть другие
- person keyser   schedule 04.05.2013
comment
Найдите медиану каждой выборки значений, которые умещаются в памяти, и возьмите медиану из них.
- person Peter Lawrey   schedule 04.05.2013
comment
Я нашел код для быстрого выбора, если он вам все еще нужен
- person aaronman   schedule 03.07.2013
Ответы (3)
Для этого существуют алгоритмы линейного времени, эта страница может быть полезной, http://en.wikipedia.org/wiki/Selection_algorithm, если вы все еще не уверены, просто спросите
По сути, алгоритм выбора работает как быстрая сортировка, но каждый раз он сортирует только на стороне поворота. Цель состоит в том, чтобы продолжить разбиение до тех пор, пока вы не выберете точку поворота, равную индексу элемента, который вы пытались найти. Вот код Java, который я нашел для быстрого выбора:
public static int selectKth(int[] arr, int k) {
if (arr == null || arr.length <= k)
throw new Error();
int from = 0, to = arr.length - 1;
// if from == to we reached the kth element
while (from < to) {
int r = from, w = to;
int mid = arr[(r + w) / 2];
// stop if the reader and writer meets
while (r < w) {
if (arr[r] >= mid) { // put the large values at the end
int tmp = arr[w];
arr[w] = arr[r];
arr[r] = tmp;
w--;
} else { // the value is smaller than the pivot, skip
r++;
}
}
// if we stepped up (r++) we need to step one down
if (arr[r] > mid)
r--;
// the r pointer is on the end of the first k elements
if (k <= r) {
to = r;
} else {
from = r + 1;
}
}
return arr[k];
}
person
aaronman
schedule
04.05.2013
Спасибо, но у меня вопрос, как использовать алгоритм, когда все числа не умещаются в памяти. Может кто-нибудь, пожалуйста, подробно объясните
- person user2316569; 05.05.2013
для этого алгоритма не обязательно сразу все числа находиться в памяти, прочтите его
- person aaronman; 05.05.2013
спасибо - не могли бы вы подтвердить мое понимание? Сначала я занесу в память первые пять чисел и найду их медиану с помощью алгоритма выбора. Сохраняю результат в памяти. Затем я заношу в память следующие пять чисел - и сохраняю их медиану в памяти. И так далее. т.е. в итоге у меня в памяти останется n / 5 номеров. Теперь я запускаю алгоритм выбора среди них, чтобы найти медиану этих чисел.
- person user2316569; 05.05.2013
Да, и затем вы используете алгоритм выбора, потому что у вас есть гарантированно хороший поворот
- person aaronman; 05.05.2013
Другое возможное решение - поддержание медианы по мере роста списка, если это вариант.
- person aaronman; 05.05.2013
person
stinepike
schedule
04.05.2013
Спасибо, но у меня вопрос, как использовать алгоритм, когда все числа не умещаются в памяти. Может кто-нибудь, пожалуйста, подробно объясните
- person user2316569; 04.05.2013
Хорошо, я отправляю описание, когда у меня будет время
- person stinepike; 05.05.2013
См. Первые два ответа на этот вопрос. Если первый (подсчет частоты) может работать для ваших данных / доступного хранилища, вы можете получить точный ответ таким образом. Второй (лечебный) - надежный общий метод.
person
Phil Steitz
schedule
04.05.2013
Существует также алгоритм с двумя кучами, который использует минимальную и максимальную кучу параллельно, чтобы найти медиану с постоянной памятью даже с большими числами.
- person Thomas Jungblut; 04.05.2013
Не могли бы вы дать ссылку, Томас, на этот алгоритм двух куч с постоянной памятью?
- person Phil Steitz; 05.05.2013
см. stackoverflow.com/questions/2579912/
- person Thomas Jungblut; 05.05.2013
Спасибо, Томас. Возможно, я неправильно понимаю настройку в статье, но я не вижу привязанного к ней хранилища. Похоже, что в итоге оказывается куча, включающая все значения. Что мне не хватает?
- person Phil Steitz; 05.05.2013