Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 数对的有效搜索_C++_Algorithm - Fatal编程技术网

C++ 数对的有效搜索

C++ 数对的有效搜索,c++,algorithm,C++,Algorithm,我有一个问题,我有一个大的数字对列表。诸如此类: (0, 1) (10, 5) (5, 6) (8, 6) (7, 5) ..... 我需要做的是,如果列表中存在一对,我可以快速查找。 我的第一个想法是制作映射容器。并使用container.find()进行搜索 第二个想法是使vector如果您不关心插入,那么可以使用排序的std::vector和std::binary\u搜索,或者std::lower\u界限 int main() { using namespace std;

我有一个问题,我有一个大的数字对列表。诸如此类:

(0,  1)
(10, 5)
(5, 6)
(8, 6)
(7, 5)
.....
我需要做的是,如果列表中存在一对,我可以快速查找。 我的第一个想法是制作
映射
容器。并使用
container.find()
进行搜索


第二个想法是使
vector如果您不关心插入,那么可以使用排序的std::vector和std::binary\u搜索,或者std::lower\u界限

int main()
{
    using namespace std;
    vector<pair<int, int>> pairs;
    pairs.push_back(make_pair(1, 1));
    pairs.push_back(make_pair(3, 1));
    pairs.push_back(make_pair(3, 2));
    pairs.push_back(make_pair(4, 1));

    auto compare = [](const pair<int, int>& lh, const pair<int, int>& rh)
        {
            return lh.first != rh.first ? 
                   lh.first < rh.first : lh.second < rh.second;
        };

    sort(begin(pairs), end(pairs), compare);
    auto lookup = make_pair(3, 1);
    bool has31 = binary_search(begin(pairs), end(pairs), lookup, compare);

    auto iter31 = lower_bound(begin(pairs), end(pairs), lookup, compare);

    if (iter31 != end(pairs) && *iter31 == lookup)
        cout << iter31->first << "; " << iter31->second << "at position "
            << distance(begin(pairs), iter31);
}
intmain()
{
使用名称空间std;
向量对;
配对。推回(使配对(1,1));
成对。向后推(形成成对(3,1));
成对。向后推(形成成对(3,2));
成对。向后推(形成成对(4,1));
自动比较=[](常数对和左侧、常数对和右侧)
{
返回左侧优先!=右侧优先?
左第一<右第一:左第二<右第二;
};
排序(开始(对)、结束(对)、比较);
自动查找=生成一对(3,1);
bool has31=二进制搜索(开始(对)、结束(对)、查找、比较);
自动iter31=下限(开始(对)、结束(对)、查找、比较);
if(iter31!=结束(对)&&*iter31==查找)

cout first如果不关心插入,可以使用排序的std::vector和std::binary\u搜索,或std::lower\u界限

int main()
{
    using namespace std;
    vector<pair<int, int>> pairs;
    pairs.push_back(make_pair(1, 1));
    pairs.push_back(make_pair(3, 1));
    pairs.push_back(make_pair(3, 2));
    pairs.push_back(make_pair(4, 1));

    auto compare = [](const pair<int, int>& lh, const pair<int, int>& rh)
        {
            return lh.first != rh.first ? 
                   lh.first < rh.first : lh.second < rh.second;
        };

    sort(begin(pairs), end(pairs), compare);
    auto lookup = make_pair(3, 1);
    bool has31 = binary_search(begin(pairs), end(pairs), lookup, compare);

    auto iter31 = lower_bound(begin(pairs), end(pairs), lookup, compare);

    if (iter31 != end(pairs) && *iter31 == lookup)
        cout << iter31->first << "; " << iter31->second << "at position "
            << distance(begin(pairs), iter31);
}
intmain()
{
使用名称空间std;
向量对;
配对。推回(使配对(1,1));
成对。向后推(形成成对(3,1));
成对。向后推(形成成对(3,2));
成对。向后推(形成成对(4,1));
自动比较=[](常数对和左侧、常数对和右侧)
{
返回左侧优先!=右侧优先?
左第一<右第一:左第二<右第二;
};
排序(开始(对)、结束(对)、比较);
自动查找=生成一对(3,1);
bool has31=二进制搜索(开始(对)、结束(对)、查找、比较);
自动iter31=下限(开始(对)、结束(对)、查找、比较);
if(iter31!=结束(对)&&*iter31==查找)

cout first
std::set
可能是一种方法,即使元素数量增加,它的性能也应该相当好(而
std::vector
的性能会很快降低,除非您事先对其进行排序并进行某种二进制或树搜索)。请记住,您必须定义一个
std::set
可能是一种方法,即使元素数量增加,它也应该表现得相当好(而
std::vector
的性能会很快降低,除非您事先对其进行排序并进行某种二进制或树搜索)。请记住,您必须定义一个
为什么不根据第一个元素对元组进行排序,然后第二个,然后二进制搜索应该是O(log(n))。

为什么不根据第一个元素对元组进行排序,然后第二个,然后二进制搜索应该是O(log(n))。

您可以使用哈希集的一些实现来更快地进行排序 例如,boost::unordered_set,其中键是std::pair。
这是最简单的方法中最快的方法。

您可以使用哈希集的一些实现来加快速度 例如,boost::unordered_set,其中键是std::pair。
这是最简单的方法中最快的方法。

如果您希望比设置查找快(比
O(lg n)
快),并且不关心项目的随机顺序,那么哈希表就是最好的选择

这不是标准的一部分,但是大多数编译器中都有一个
散列集

如果您想进行真正的快速搜索,您可以尝试。但是,它们有时会导致误报(即,在没有项目对的情况下检测到有项目对),并且需要大量内存。合适的Bloom筛选器实现可能是:

const int MAX_HASH = 23879519; // note it's prime; must be 2-5 times larger than number of your pairs
vector<bool> Bloom(MAX_HASH); // vector<bool> compresses bools into bits

// multiply one by a large-ish prime, add the second, return modulo another prime
// then use it as the key for the filter
int hash(long long a, long long b) {
    return (a*15485863LL + b) % MAX_HASH;
}

// constant-time addition
void add_item(pair<int,int> p) {
    Bloom[hash(p.first, p.second)] = true;
}

// constant-time check
bool is_in_set(pair<int,int> p) {
    return Bloom[hash(p.first, p.second)];
}
const int MAX_HASH=23879519;//注意它是素数;必须比成对数大2-5倍
向量Bloom(MAX_HASH);//向量将布尔压缩为位
//用一个大素数乘以一个大素数,再加上第二个,返回另一个素数的模
//然后将其用作过滤器的键
int散列(长a、长b){
返回(a*15485863LL+b)%MAX\u散列;
}
//恒定时间加法
无效添加项(对p){
Bloom[hash(p.first,p.second)]=true;
}
//定时检查
布尔值在集合中(对p){
返回Bloom[hash(p.first,p.second)];
}

如果您希望比设置查找快(比
O(lg n)
快),并且不关心项目的随机顺序,那么哈希表就是一种方法

这不是标准的一部分,但是大多数编译器中都有一个
散列集

如果您想进行真正的快速搜索,您可以尝试。但是,它们有时会导致误报(即,在没有项目对的情况下检测到有项目对),并且需要大量内存。合适的Bloom筛选器实现可能是:

const int MAX_HASH = 23879519; // note it's prime; must be 2-5 times larger than number of your pairs
vector<bool> Bloom(MAX_HASH); // vector<bool> compresses bools into bits

// multiply one by a large-ish prime, add the second, return modulo another prime
// then use it as the key for the filter
int hash(long long a, long long b) {
    return (a*15485863LL + b) % MAX_HASH;
}

// constant-time addition
void add_item(pair<int,int> p) {
    Bloom[hash(p.first, p.second)] = true;
}

// constant-time check
bool is_in_set(pair<int,int> p) {
    return Bloom[hash(p.first, p.second)];
}
const int MAX_HASH=23879519;//注意它是素数;必须比成对数大2-5倍
向量Bloom(MAX_HASH);//向量将布尔压缩为位
//用一个大素数乘以一个大素数,再加上第二个,返回另一个素数的模
//然后将其用作过滤器的键
int散列(长a、长b){
返回(a*15485863LL+b)%MAX\u散列;
}
//恒定时间加法
无效添加项(对p){
Bloom[hash(p.first,p.second)]=true;
}
//定时检查
布尔值在集合中(对p){
返回Bloom[hash(p.first,p.second)];
}

如果您的单个数字是
int
s,这里有另一个解决方案

  • 用两个
    int
    s构建一个
    long
    (第一个
    int
    可以是高32位,第二个
    int
    可以是低32位)
  • 将其插入到
    无序集
    (或
    ,或排序的
    向量
    -配置文件中以查找匹配项)
  • 找到
  • 应该比工作快一些