Учитывая два списка (не обязательно отсортированные), каков наиболее эффективный нерекурсивный алгоритм для поиска пересечения этих списков?Эффективный алгоритм пересечения списков
ответ
Вы можете поместить все элементы первого списка в хэш-набор. Затем повторите итерацию второго, и для каждого из его элементов проверьте хэш, чтобы увидеть, существует ли он в первом списке. Если это так, выведите его как элемент пересечения.
Звучит неплохо, но я не верю, что у меня есть доступ к алгоритмам хэширования. Какие-либо предложения? – 2009-01-30 21:42:46
Тогда, возможно: * сортировать список1 (время: n log n) * sort list2 (время: n log n) * объединить эти два и проверить аналогичные записи, когда вы повторяете два отсортированных списка одновременно (линейное время) – Frank
У меня недостаточно очков для комментариев к другим темам, но в отношении того, что быстрая сортировка рекурсивна: вы можете реализовать ее без рекурсии. См. Здесь, например: http://www.codeguru.com/forum/archive/index.php/t-333288.html – Frank
Во-первых, сортировать оба списка с помощью быстрой сортировки: O (. П * журнала (п) Затем сравните списки, просматривая наименьшие значения первого и добавить общие ценности, например, в Lua.):
function findIntersection(l1, l2)
i, j = 1,1
intersect = {}
while i < #l1 and j < #l2 do
if l1[i] == l2[i] then
i, j = i + 1, j + 1
table.insert(intersect, l1[i])
else if l1[i] > l2[j] then
l1, l2 = l2, l1
i, j = j, i
else
i = i + 1
end
end
return intersect
end
который является O(max(n, m))
, где n
и m
- размеры листинга.
EDIT: быстрая сортировка является рекурсивным, как сказано в комментариях, но, похоже, есть non-recursiveimplementations
Является ли quicksort рекурсивным? Или есть нерекурсивная версия? – 2009-01-30 21:50:18
Слишком плохо, что quicksort является рекурсивным алгоритмом ... – oefe
Я бы не назвал это O (max (n, m)). Вы тоже делаете два вида. –
без хеширования, я полагаю, у вас есть два варианта:
- Наивный способ собирается сравнить каждый элемент с каждым другим элементом. O (N^2)
- Другой способ будет первым сортировать списки, а затем перебрать их: O (п Л.Г. п) * 2 + 2 * O (п)
И еще одно: если можно добавить свойство к каждому элементу, сначала сбрасываем его на ноль для всех элементов в обоих наборах, а затем устанавливаем его в 1 в одном из наборов, затем просматриваем второй набор элементов поиска со свойством установленное значение 1. Это 'O (n + m)', но не всегда возможно. –
Возможно, его можно улучшить с помощью двоичного поиска O (log n)? – knight
Просто обратите внимание, что 'O (n lg n) * 2 + O (n) * 2' совпадает с' O (n lg n) '. – porglezomp
Я получил некоторые хорошие ответы от this, которые вы можете применить. У меня пока нет возможности попробовать их, но поскольку они также охватывают пересечения, вы можете найти их полезными.
Почему бы не реализовать свою собственную простую хэш-таблицу или хэш-набор? Стоит избегать пересечения nlogn, если ваши списки большие, как вы говорите.
Поскольку вы знаете немного о своих данных заранее, вы должны иметь возможность выбрать хорошую хэш-функцию.
Если есть поддержка sets (как вы их называете в названии), так как встроенный обычно есть метод пересечения.
В любом случае, поскольку кто-то сказал, что вы можете сделать это легко (я не буду отправлять код, кто-то уже сделал это), если у вас отсортированы списки. Если вы не можете использовать рекурсию, проблем нет. Существуют версии quick sort recursion-less.
1. Если eviews будет поддерживать наборы, он, вероятно, предложит метод для заданных пересечений. 2. Как можно объединить два набора. Пересечение - это те элементы, которые находятся в обоих наборах. Когда я прихожу сюда, я думаю о вычислении объединения двух наборов – f3lix
Да, вы правы, я не обращал внимания. Я отредактировал :) –
java имеет поддержку наборов, но не имеет встроенных функций пересечения. – lensovet
Я второй вариант «устанавливает». В JavaScript вы можете использовать первый список для заполнения объекта, используя элементы списка в качестве имен. Затем вы используете элементы списка из второго списка и видите, существуют ли эти свойства.
В PHP, что-то вроде
function intersect($X) { // X is an array of arrays; returns intersection of all the arrays
$counts = Array(); $result = Array();
foreach ($X AS $x) {
foreach ($x AS $y) { $counts[$y]++; }
}
foreach ($counts AS $x => $count) {
if ($count == count($X)) { $result[] = $x; }
}
return $result;
}
Если у вас есть дубликаты в любом из массивов, вы получите неправильное поведение. – Slawek
в C++ можно попробовать с помощью STL карта
vector<int> set_intersection(vector<int> s1, vector<int> s2){
vector<int> ret;
map<int, bool> store;
for(int i=0; i < s1.size(); i++){
store[s1[i]] = true;
}
for(int i=0; i < s2.size(); i++){
if(store[s2[i]] == true) ret.push_back(s2[i]);
}
return ret;
}
Вы можете посмотреть на фильтры Блума следующее. Это битовые векторы, которые дают вероятностный ответ, является ли элемент членом набора. Установить пересечение может быть реализовано с помощью простой побитовой операции И. Если у вас большое количество нулевых пересечений, фильтр Bloom может помочь вам быстро их устранить. Однако вам все равно придется прибегнуть к одному из других алгоритмов, упомянутых здесь, для вычисления фактического пересечения. http://en.wikipedia.org/wiki/Bloom_filter
Это увлекательный подход для эффективного определения того, перекрываются ли два больших набора. –
Из eviews features list кажется, что она поддерживает сложные слияния и объединения (если это «присоединиться», как в терминологии БД, она будет вычислить пересечение). Теперь копаться в документации :-)
Дополнительно, Eviews имеет свой собственный пользовательский форум - почему бы не спросить there_
с множеством 1 построить бинарное дерево поиска с O(log n)
и перебирать set2 и поиск в BST m X O(log n)
так общее O(log n) + O(m)+O(log n) ==> O(log n)(m+1)
Для части дерева двоичного поиска необходимо отсортировать один из списков (который добавит O (m log m) или O (n log n) к сложности). Это по-прежнему очень полезный ответ: в моем случае у меня есть два списка, содержащих одни и те же объекты, но каждый из них отсортирован по различным атрибутам объекта, и мне нужно получить, какие объекты находятся в обоих списках. Этот ответ агностик атрибуту, по которому сортируется каждый список. Благодаря! – yasashiku
На самом деле, построение дерева O (n log n), так что это O ((n + m) log n) total –
Вот еще одно возможное решение, которое я придумал для выполнения O (nlogn) во временной сложности и без дополнительного хранения. Вы можете это проверить здесь https://gist.github.com/4455373
Вот как это работает: Предполагая, что наборы не содержат повторений, объедините все наборы в один и отсортируйте. Затем пропустите объединенный набор и на каждой итерации создайте подмножество между текущим индексом i и i + n, где n - количество наборов, доступных во юниверсе. То, что мы ищем в качестве цикла, представляет собой повторяющуюся последовательность размера n, равную числу множеств во Вселенной.
Если это подмножество в i равно этому подмножеству в точке n, это означает, что элемент at i повторяется n раз, что равно общему числу множеств. И поскольку в любом наборе нет повторений, что означает, что каждый из наборов содержит это значение, поэтому мы добавляем его к пересечению. Затем мы сдвигаем индекс на i + то, что осталось между ним и n, потому что определенно ни один из этих индексов не собирается формировать повторяющуюся последовательность.
Сортировка связанного списка не может быть nlogn – shinzou
Из определения Big-Oh обозначений:
Т (N) = O (F (N)), если существуют положительные константы с и п 0, что Т (N) ≤ ср (N), когда N ≥ n 0.
На практике это означает, что если эти два списка относительно невелики по размеру, говорят, что менее 100 элементов в каждой из двух циклов работают очень хорошо. Завершите первый список и найдите аналогичный объект во втором. В моем случае это работает просто отлично, потому что у меня не будет больше 10 - 20 максимальных элементов в моих списках. Однако хорошее решение - это сортировка первого O (n log n), сортировка второго также O (n log n) и объединение их, другое O (n log n), грубо говорящее O (3 n log n), скажем что два списка имеют одинаковый размер.
Использование skip pointers и SSE instructions может улучшить эффективность пересечения списков.
- 1. Алгоритм пересечения
- 2. Эффективный алгоритм для сравнения только обновленных списков
- 3. Эффективный алгоритм сравнения частей списков, содержащих наборы
- 4. Многомерный алгоритм пересечения
- 5. алгоритм пересечения O (n) лучше?
- 6. Эффективный алгоритм для сопоставления сегментов линии без пересечения
- 7. Эффективный алгоритм пересечения карты беспорядочно с использованием ключа
- 8. Каков самый быстрый алгоритм для пересечения двух отсортированных списков?
- 9. Алгоритм пересечения сетки и конуса
- 10. Несущественный алгоритм пересечения несортированных C++
- 11. Пролог пересечения трех списков
- 12. 3D линии пересечения алгоритм
- 13. Алгоритм пересечения окружности
- 14. алгоритм пересечения сегментов линии
- 15. алгоритм наименьших пограничными Пересечения
- 16. Алгоритм для пересечения многоугольников
- 17. Алгоритм пересечения ребер?
- 18. Поиск пересечения 2 отсортированных списков
- 19. алгоритм поиска списков
- 20. Эффективный алгоритм для переименования
- 21. Есть ли эффективный алгоритм для нечеткой дедупликации списков строк?
- 22. Алгоритм оптимального «пересечения» двух результатов?
- 23. Быстрый алгоритм пересечения эллипсоида (ов)
- 24. Алгоритм линейного пути пересечения точек
- 25. Алгоритм для пересечения текста текста
- 26. Эффективный алгоритм скремблирования слов
- 27. Эффективный поиск вложенных списков
- 28. Эффективный кортеж алгоритм поиска
- 29. Эффективный бит переназначения алгоритм
- 30. f # fibbonaci эффективный алгоритм
Это звучит как вопрос о домашнем задании - не так ли? –
На самом деле нет. Я работаю, и мне приходится программировать в среде статистического моделирования, называемой eviews. Eviews не имеет встроенного пересечения, а также не поддерживает рекурсию. Мне нужен быстрый алгоритм, потому что мои наборы, как правило, большие, и программа должна выполняться часто. Благодаря! – 2009-01-30 21:40:51
На каком языке вы? Возможно, на вашем языке уже есть что-то, что облегчит задачу. – Juliet