У меня есть два больших наборов целых чисел и . Каждый набор содержит около миллиона записей, и каждая запись представляет собой положительное целое число длиной не более 10 цифр.
Каков наилучший алгоритм для вычисления и ? Другими словами, как я могу эффективно вычислить список записей , которых нет в и наоборот? Какова была бы лучшая структура данных для представления этих двух наборов, чтобы сделать эти операции эффективными?
Лучший подход, который я могу предложить, - это хранить эти два набора в виде отсортированных списков и сравнивать каждый элемент с каждым элементом линейным образом. Можем ли мы сделать лучше?
algorithms
data-structures
sets
user917279
источник
источник
Ответы:
Если вы хотите хранить наборы в специализированной структуре данных, вы можете получить некоторые интересные сложности.
ПустьI=O(min(|A|,|B|,|AΔB|))
Затем вы можете выполнять операции над множествами и A Δ B , каждая в O ( I ⋅ log | A | + | B |A∪B,A∩B,A∖B AΔB ожидаемое время Таким образом, по существу, вы получаете минимальный размер двух наборов или размер симметричной разности, в зависимости от того, что меньше. Это лучше, чем линейное, если симметричная разница мала; то есть. если они имеют большое пересечение. Фактически, для двух требуемых операций разности множеств это практически чувствительно к выходу, поскольку вместе они составляют размер симметричной разности.O ( я⋅ журнал| A | + | Б |я)
См. Confluently Persistent Sets и Maps by Olle Liljenzin (2013) для получения дополнительной информации.
источник
Лучшее, что я знаю, это линейное сканирование, если наборы представлены в виде отсортированных связанных списков. Время работы .O ( | A | + | B | )
Я представлял это в псевдо-Python. Если вы не читаете Python, он
A[0]
является главой связанного спискаA
,A[1:]
является остальной частью списка и+
представляет собой объединение списков. По соображениям эффективности, если вы работаете в Python, вы, вероятно, не захотите реализовать его точно так же, как описано выше - например, может быть лучше использовать генераторы, чтобы избежать создания многих временных списков - но я хотел показать вам идеи в простейшей форме. Цель этого псевдокода - просто проиллюстрировать алгоритм, а не предложить конкретную реализацию.источник
Если A и B имеют одинаковый размер, непересекающиеся и чередующиеся (например, нечетные числа в A и четные числа в B), тогда парное сравнение элементов в линейном времени, вероятно, является оптимальным.
Если A и B содержат блоки элементов, которые находятся точно в одном из A или B или в обоих из них, можно вычислить разность множеств, объединение и пересечение за сублинейное время. Например, если A и B отличаются ровно одним элементом, то разницу можно вычислить в O (log n).
http://arxiv.org/abs/1301.3388
источник
источник
long
может хранить 32 элемента или 1byte
, 8 элементов. Таким образом, 1М записи могут храниться только в ~ 125K RAM! хранилище может быть значительно более эффективным, чем другие представления, в зависимости от того, как реализована проблема ...