Считаем, что есть некоторые списки целых чисел:
#--------------------------------------
0 [0,1,3]
1 [1,0,3,4,5,10,...]
2 [2,8]
3 [3,1,0,...]
...
n []
#--------------------------------------
Вопрос заключается в объединении списков, имеющих хотя бы один общий элемент. Таким образом, результаты только для данной части будут следующими:
#--------------------------------------
0 [0,1,3,4,5,10,...]
2 [2,8]
#--------------------------------------
Каков наиболее эффективный способ сделать это на больших данных (элементы - это просто цифры)?
Структура tree
что-то думать?
Теперь я делаю эту работу, конвертируя списки в sets
и итерации для пересечений, но это медленно! Кроме того, я чувствую, что это так элементарно! Кроме того, в реализации не хватает чего-то (неизвестного), потому что некоторые списки остаются незанятыми когда-нибудь! Сказав это, если вы предлагаете самореализацию, будьте щедры и обеспечьте простой пример кода [по-видимому Python является моим фаворитом:)] или pesudo-code.
Обновление 1:
Вот код, который я использовал:
#--------------------------------------
lsts = [[0,1,3],
[1,0,3,4,5,10,11],
[2,8],
[3,1,0,16]];
#--------------------------------------
Функция (багги!!):
#--------------------------------------
def merge(lsts):
sts = [set(l) for l in lsts]
i = 0
while i < len(sts):
j = i+1
while j < len(sts):
if len(sts[i].intersection(sts[j])) > 0:
sts[i] = sts[i].union(sts[j])
sts.pop(j)
else: j += 1 #---corrected
i += 1
lst = [list(s) for s in sts]
return lst
#--------------------------------------
Результат:
#--------------------------------------
>>> merge(lsts)
>>> [0, 1, 3, 4, 5, 10, 11, 16], [8, 2]]
#--------------------------------------
Обновление 2:
По моему опыту, код, приведенный Niklas Baumstark ниже, показал, что для простых случаев бит был быстрее. Не проверен метод, данный "Hooked" еще, так как это совершенно другой подход (кстати, это кажется интересным).
Процедура тестирования для всех из них может быть очень трудной или невозможной для обеспечения результатов. Реальный набор данных, который я буду использовать, является настолько большим и сложным, что невозможно проследить любую ошибку, просто повторяя. Это то, что я должен быть на 100% удовлетворен надежностью метода, прежде чем нажимать его на свое место в рамках большого кода в качестве модуля. Просто сейчас метод Niklas выполняется быстрее, и ответ на простые наборы, конечно, правильный.
Однако, как я могу быть уверен, что он хорошо работает для реального большого набора данных? Так как я не буду отслеживать ошибки визуально!
Обновление 3: Обратите внимание, что надежность метода гораздо важнее скорости для этой проблемы. Я надеюсь, что смогу перевести код Python на Fortran для максимальной производительности.
Обновление 4:
На этом посту есть много интересных моментов и щедро даны ответы, конструктивные комментарии. Я бы рекомендовал внимательно прочитать все. Примите мою признательность за разработку вопроса, замечательных ответов и конструктивных комментариев и обсуждений.