C++ 计算每对向量的副本的有效方法是什么?

C++ 计算每对向量的副本的有效方法是什么?,c++,vector,duplicates,std-pair,C++,Vector,Duplicates,Std Pair,有没有有效的方法来计算向量中每对的重复数? 例如,如果我有这样一个向量: vector<pair<int, int> > duplicates={{1,2},{3,2},{2,1},{5,6},{5,6},{1,2},{2,1},{5,6}}; 说清楚一点,我只是好奇如何更有效地解决这个问题。我试着比较每一对向量,这似乎不是一个聪明的方法 一种简单的方法是使用地图或无序地图进行计数: #include <iostream> #include <vec

有没有有效的方法来计算向量中每对的重复数? 例如,如果我有这样一个向量:

 vector<pair<int, int> > duplicates={{1,2},{3,2},{2,1},{5,6},{5,6},{1,2},{2,1},{5,6}};

说清楚一点,我只是好奇如何更有效地解决这个问题。我试着比较每一对向量,这似乎不是一个聪明的方法

一种简单的方法是使用地图或无序地图进行计数:

#include <iostream>
#include <vector>
#include <map>
int main( int argn, char **argc)
{
    std::vector<std::pair<int, int> > duplicates={{1,2},{3,2},{2,1},{5,6},{5,6},{1,2},{2,1},{5,6}};
    std::map<std::pair<int, int>, int> checker;
    for (const auto &elem: duplicates)
    {
        ++checker[elem];
    }

    for (const auto &elem: checker) std::cout << "{" << elem.first.first <<
                                                 "," << elem.first.second <<
                                                 "}: " << elem.second << std::endl;

    return 0;
}
请注意,映射插入/恢复是Ologn,循环使其成为aprox。On*logn

编辑:

在OP的附加说明之后,下面是一个使用无序映射的更快更好的实现:

#include <iostream>
#include <vector>
#include <unordered_map>

namespace std
{
template <>
struct hash<std::pair<int,int>>
{
    size_t operator()(pair<int, int> const &p) const
    {
        // Fine for 64bit size_t and 32bit int. Otherwise, some collision may happens.
        size_t result = (static_cast<size_t>(p.first) <<(sizeof(std::size_t)<<2))
                        + static_cast<size_t>(p.second);
        return result;
    }
};
}

int main( int argn, char **argc)
{
    std::vector<std::pair<int, int> > duplicates={{1,2},{3,2},{2,1},{5,6},{5,6},{1,2},{2,1},{5,6}};
    std::unordered_map<std::pair<int, int>, int> checker;
    for (const auto &elem: duplicates)
    {
        ++checker[elem]; // value initialized with 0
    }

    for (const auto &elem: checker) std::cout << "{" << elem.first.first <<
                                                 "," << elem.first.second <<
                                                 "}: " << elem.second << std::endl;

    return 0;
}
在无序的_映射中插入,使用散列使其通常保持不变,更糟糕的是,当存在线性冲突时。最终的平均复杂度为


我有一个简单的解决方案:

成对排序向量 然后只要一个循环,如果匹配连续对,则增加计数器 一般搜索复杂度:n*n
此搜索复杂性:nlogn

提示:使用检测重复项的关联容器。SO在这里帮助您完成任务,而不是为您完成任务。你应该展示你已经尝试过的东西。@PaulRooney我认为,这个问题没有问题。Lixum只要求技术或逻辑,而不是编码解决方案。@ShohanAhmedSijan OP应该澄清他们在寻找什么,这就是为什么这个问题被否决的原因。我只是好奇如何更有效地解决这个问题。-哈希表和计数器-但这就是std::unordered_映射的全部内容。不需要if语句。if checker.findelem==checker.end checker[elem]=1;else部分是多余的。你最新的编辑仍然有if语句-去掉它。检查std::map::operator[]的行为,特别是when键不存在的部分…@AdrianMaire如果我们每天都能学到一些新东西,这是一件好事
#include <iostream>
#include <vector>
#include <unordered_map>

namespace std
{
template <>
struct hash<std::pair<int,int>>
{
    size_t operator()(pair<int, int> const &p) const
    {
        // Fine for 64bit size_t and 32bit int. Otherwise, some collision may happens.
        size_t result = (static_cast<size_t>(p.first) <<(sizeof(std::size_t)<<2))
                        + static_cast<size_t>(p.second);
        return result;
    }
};
}

int main( int argn, char **argc)
{
    std::vector<std::pair<int, int> > duplicates={{1,2},{3,2},{2,1},{5,6},{5,6},{1,2},{2,1},{5,6}};
    std::unordered_map<std::pair<int, int>, int> checker;
    for (const auto &elem: duplicates)
    {
        ++checker[elem]; // value initialized with 0
    }

    for (const auto &elem: checker) std::cout << "{" << elem.first.first <<
                                                 "," << elem.first.second <<
                                                 "}: " << elem.second << std::endl;

    return 0;
}