Я новый участник этого форума, надеюсь, вы не забыли об этом старом вопросе:)
Решение
Сохраните основной набор в индексированной структуре данных - например, какмассив (или массив, если ваша библиотека поддерживает это).Предположим, вы можете связать идентификатор с каждым набором (если нет, то как узнать, какой набор получить?).Итак, теперь нам нужен способ выяснить, какие элементы вашего массива участвуют в этом наборе, а какие нет.
Используйте матрицу (n x m)
, где n
- это количество элементов в вашем массиве.и m
- начальное количество комплектов.i относится к индексу строки, а j относится к индексу столбца.
A[i][j] = 0 if ith element is not in jth set
A[i][j] = 1 if ith element is in jth set
Не используйте простой двумерный массив, выберите ArrayList<ArrayList>
.Java / C # / C ++ поддерживают такие общие конструкции, но это не должно быть очень сложно сделать в других языках, таких как Perl.В C # вы даже можете использовать DataTable
.
Время, чтобы добавить новый набор
Вы можете добавить новый набор за O(n)
время.Просто добавьте новый столбец для этого набора и установите соответствующие строки в 1 для этого столбца.Нет необходимости сортировать этот набор, пока исходный массив отсортирован.
Время добавления нового элемента
В простом отсортированном массиве время для вставки равно O(log n)
.В нашем случае мы сначала добавим элемент в массив (и при любом индексе, в который мы добавили элемент, матрица также получит строку всего 0
с этим индексом).Затем мы устанавливаем записи в этом столбце равными 1, если элемент принадлежит набору.Таким образом, наихудшим временем выполнения становится O(log n) + O(m)
.
Время для извлечения первых N элементов из набора
Выберите столбец, соответствующий набору во времени O(1)
, а затем выберитепервые N
записи, которые 1
.Это будет линейно.
Время объединения двух наборов
Допустим, мы объединяем наборы в j1 и j2 в третий набор в j3.
for (int i = 0; i < n - 1; i++) {
A[i][j3] = A[i][j1] | A[i][j2];
}
Этоснова линейно.
Время для удаления элемента
Сначала найдите элемент в мастер-массиве - это займет O(log n)
времени.Затем удалите его из этого массива и удалите строку с этим индексом из матрицы.
Эффективные удаления из массива
Не просто удаляйте, просто пометьте их как несуществующие.По пороговому количеству несуществующих столбцов / строк вы можете объединиться.Точно так же, начните с высокой емкости изначально для массивов.Современные реализации должны делать это автоматически, хотя.