2016-08-04 185 views
1

這是我的問題:我有一個std::vector<std::unordered_set<int>>。其中一些無序集合是平等的但不是相同的順序(我知道順序在unordered_set中是不明確的)。要刪除重複項(在集合的數學意義上,例如{1,3,2} == {3,2,1}),我想過使用std::unique(),但這不起作用。搜索後,我甚至注意到矢量中的數據需要排序,這在這種情況下是沒有意義的。是否有刪除std::vector<std::unordered_set<int>>中的重複項的功能?我可以自己做,我只想知道,如果我錯過了一些事情。另外,如果你知道如何使用不同的容器來解決這個問題,那麼讓我知道。效率在這裏不是一個大問題,在這種情況下,該矢量中不超過200個元素。在std :: vector上使用std :: unique()<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>>,並拿出一個哈希值是獨立排序的,這樣你就不必做任何的這個開始。

+0

如果效率很重要,我認爲使用'boost :: multi_index'會更容易,並且同時具有無序和有序訪問。 – Slava

+0

不'std :: unique'是否需要相同的lambda來檢測重複? – Slava

+0

@Slava「唯一」的謂詞是比較兩個元素的相等性。 '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

一旦你從'unordered_set'移動到'set',你可以排序和唯一的代替... – Yakk

相關問題