【问题标题】:Determine if there are duplicates in vector判断向量中是否有重复项
【发布时间】:2018-03-13 09:38:44
【问题描述】:

我想确定向量中是否存在重复项。这里最好的选择是什么?

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)
{
  //
}

【问题讨论】:

  • std::unique 在做什么以及返回什么?
  • 如果问题只是“是否有 any 重复项”,std::unique 是多余的,因为它会删除 all 重复项。这就是为什么您会得到建议 std::adjacent_find 的答案,它会在找到第一个重复项时返回。
  • Determining if an unordered vector<T> has all unique elements 的可能重复项。请注意,@UdayrajDeshmukh 链接的问题被标记为我链接的问题的副本。

标签: c++ vector stl unique


【解决方案1】:

“最佳”选项不存在。这取决于您如何定义“最佳”。

这里有一些解决方案,每个都有自己的优点和缺点:

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;
}

【讨论】:

    【解决方案2】:

    如果没有重复,则从unique 返回的迭代器是结束迭代器。所以:

    if (it != arrLinkToClients.end())
        cout << "Some duplicates found!";
    

    【讨论】:

    • 返回值是指向范围新端的前向迭代器,所以你不能这样做。
    • @0xBADF00 -- std::unique 返回的迭代器与调用函数的迭代器具有相同的类型。这个比较没有错。
    • @PeteBecker 好吧,我的错,你当然可以这样做,但它不会完成 OP 想要的。
    • @0xBADF00 — 我觉得没问题。为什么说不行?
    • @PeteBecker 好吧,我显然很愚蠢,它很好用(没想到排序)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2017-06-27
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多