У меня есть вектор множеств, и я хочу удалить все наборы, которые являются подмножествами других множеств в векторе. Пример:Лучший способ удалить элементы Vec в зависимости от других элементов того же Vec
a = {0, 3, 5}
b = {0, 5}
c = {0, 2, 3}
В этом случае я хотел бы удалить b
, потому что это подмножество a
. Я в порядке с использованием «немого» алгоритма n².
К сожалению, довольно сложно заставить его работать с заемщиком. Лучшее, что я придумал это (Playground):
let mut v: Vec<HashSet<u8>> = vec![];
let mut to_delete = Vec::new();
for (i, set_a) in v.iter().enumerate().rev() {
for set_b in &v[..i] {
if set_a.is_subset(&set_b) {
to_delete.push(i);
break;
}
}
}
for i in to_delete {
v.swap_remove(i);
}
(примечание: приведенный выше код не исправить Смотрите комментарии для получения более подробной информации!)
Я вижу несколько недостатков:
- мне нужен дополнительный вектор с дополнительными ассигнованиями
- Может быть, есть более эффективные способы, чем вызов
swap_remove
часто - Если мне нужно сохранить порядок, я не могу использовать
swap_remove
, но должен использоватьremove
, который медленно
Есть ли лучший способ сделать это? Я не просто спрашиваю о моем случае использования, а об общем случае, как описано в названии.
Этот алгоритм неверен; он удаляет только множества, являющиеся подмножествами * ранних * множеств в векторе. Пример: https://play.rust-lang.org/?gist=88e20f4386f3d5df3fe57fe3a1372dfa&version=stable&backtrace=0 –
Примечание: сохранение порядка и избежание перераспределения может быть достигнуто путем создания временного (и нажатия в порядке), а затем поменять его оригиналом , Пока неясно, что такое переломный момент. –
Сохраняет ли заказ заказ здесь? Если нет, я сначала сортирую вектор по размеру, так что вы можете избежать необходимости подмножества проверять оба пути (и удалить правильный). –