在std :: vector上使用std :: unique()>

问题描述:

这是我的问题:我有一个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)时间中的重复项。 –

效率是不是在这里

一个大问题,那我们去野外! 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

谢谢你们。我遵循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