2016-08-04 2 views
1

Вот моя проблема: у меня есть std::vector<std::unordered_set<int>>. Некоторые из этих неупорядоченных множеств равны, но не в том же порядке (я знаю, что порядок неоднозначен в unordered_set). Чтобы удалить дубликаты (в математическом смысле набора, например {1,3,2} == {3,2,1}), я подумал об использовании std::unique(), но это не сработает. После поиска я даже заметил, что данные в векторе нужно сортировать, что не имеет смысла в этом случае. Есть функция, которая удаляет дубликаты в std::vector<std::unordered_set<int>>? Я мог бы сделать это сам, я просто хочу знать, пропустил ли я что-то в stl. Кроме того, если вы знаете, как решить эту проблему, используя разные контейнеры, сообщите мне об этом. Эффективность здесь не большая проблема, в этом контексте в этом векторе не более 200 элементов.Использование std :: unique() на std :: vector <std :: unordered_set <T>>

TLDR; Как удалить дубликаты в std::vector<std::unordered_set<int>>?

+0

Есть ли причина, вы используете 'unordered_set' над' set'? Если вы использовали 'set', два набора, содержащие одни и те же элементы, имели бы тот же порядок. – NathanOliver

+0

Вы можете удалить дубликаты в O (n^2) раз, сравнив (для равенства) каждый элемент массива с каждым другим элементом массива. –

ответ

1

Эффективность не является большой проблемой здесь

Тогда давайте дикие! set имеет operator<, поэтому давайте просто создадим их на лету!

std::vector<std::unordered_set<int>> v = ...; 
std::sort(v.begin(), v.end(), [](auto const& lhs, auto const& rhs){ 
    return std::set<int>(lhs.begin(), lhs.end()) < 
     std::set<int>(rhs.begin(), rhs.end()); 
}); 
v.erase(std::unique(v.begin(), v.end()), v.end()); 

Это, безусловно, довольно плохо, поскольку время работы идет, но оно работает!


Или вы могли бы сделать unordered_set<unordered_set<int>> и придумать Hash, что это не зависит от заказа, так что вы не должны делать все это, чтобы начать с.

+0

Если эффективность важна, я думаю, что было бы проще использовать 'boost :: multi_index' и иметь неупорядоченный и упорядоченный доступ в одно и то же время. – Slava

+0

Не требует ли 'std :: unique' одинаковой лямбда обнаружить дубликаты? – Slava

+0

@Slava Предикат для 'unique' - это сравнение двух элементов для равенства. 'unordered_set' уже равно EqualityComparable. – Barry

0

Спасибо, ребята. Я следил за советом n.m, поскольку я думаю, что это действительно было самое простое. выглядит так:

std::vector<std::set<int>> resultP; 
............................................... 
// Remove the duplicate (without order), we want combinations not permutations. 
std::vector<std::set<int>> resultC; 
bool permAlreadyThere = false; 
for (auto& perm : resultP) 
{ 
    for (auto& comb : resultC) 
    { 
     if (perm == comb) 
     { 
      permAlreadyThere = true; 
      break; 
     } 
    } 
    if (!permAlreadyThere) resultC.push_back(perm); 
    permAlreadyThere = false; 
} 
+0

Как только вы перейдете к 'set' из' unordered_set', вы можете сортировать и уникально вместо этого ... – Yakk

Смежные вопросы