Search code examples
c++vectorstlunique

Determine if there are duplicates in vector


I would like to determine if there are duplicates in a vector. What is the best option here?

sort(arrLinkToClients.begin(), arrLinkToClients.end(), [&](const type1& lhs,const type1& rhs)
{
    lhs.nTypeOfLink < rhs.nTypeOfLink;
});

auto it = unique(arrLinkToClients.begin(), arrLinkToClients.end(), [&](const type1& lhs, const type1& rhs)
{
    lhs.nTypeOfLink == rhs.nTypeOfLink;
});

//how to check the iterator if there are duplicates ?
if (it)
{
  //
}

Solution

  • The "best" option does not exist. It depends on how you define "best".

    Here are some solutions, each with their own advantages and disadvantages:

    Using map
    template <class T>
    auto has_duplicates(const std::vector<T>& v) -> bool
    {
        std::unordered_map<T, int> m;
    
        for (const auto& e : v)
        {
            ++m[e];
    
            if (m[e] > 1)
                return true;
        }
        return false;
    }
    
    Using set
    template <class T>
    auto has_duplicates(const std::vector<T>& v) -> bool
    {
        std::unordered_set<int> s;
        std::copy(v.begin(), v.end(), std::inserter(s, s.begin());
       
        return v.size() != s.size();
    }
    
    Using sort and adjacent_find (mutating range)
    template <class T>
    auto has_duplicates(std::vector<T>& v) -> bool
    {
        std::sort(v.begin(), v.end());
    
        return std::adjacent_find(v.begin(), v.end()) != v.last();
    }
       
    
    Manual iteration with std::find
    template <class T>
    auto has_duplicates(const std::vector<T>& v) -> bool
    {
        for (auto it = v.begin(); it != v.end(); ++it)
            if (std::find(it + 1, v.end(), *it) != v.end())
                return true;
                
        return false;
    }
    
    Manual iteration
    template <class T>
    auto has_duplicates(const std::vector<T>& v) -> bool
    {
        for (auto i1 = v.begin(); i1 != v.end(); ++i1)
            for (auto i2 = i1 + 1; i2 != v.end(); ++i2)
                if (*i1 == *i2)
                    return true;
        
        return false;
    }