C++ 比较它们之间的元素并获得公共值的键

C++ 比较它们之间的元素并获得公共值的键,c++,algorithm,key,containers,matching,C++,Algorithm,Key,Containers,Matching,我在两个不同的集合中拥有成对的数据、键和值。我需要比较两个集合的值,并创建一个集合,其中包含相等值的键对 例如,使用以下数据集: Vals Key Col1 Col2 1 4 5 2 6 9 4 8 4 6 10 10 常用值为4和10。所以他的想法是得到一个新的成对集合,在这个例子中(keycol1,keycol2){{{1,4},{6,6} 我需要一种最快的方法来实现这一点,每个集合可以轻松地拥有100k的数据,而使用for

我在两个不同的集合中拥有成对的数据、键和值。我需要比较两个集合的值,并创建一个集合,其中包含相等值的键对

例如,使用以下数据集:

      Vals
Key Col1 Col2
1    4     5
2    6     9
4    8     4
6    10    10
常用值为4和10。所以他的想法是得到一个新的成对集合,在这个例子中(keycol1,keycol2){{{1,4},{6,6}

我需要一种最快的方法来实现这一点,每个集合可以轻松地拥有100k的数据,而使用for循环进行迭代太慢了,我尝试使用vector

这两个集合不一定具有相同的键(如map),并且数据可能不是int(我使用二进制数据,通常键是int(无单键长)

下面是我的示例代码(非常非常慢的代码):

struct p{
无符号长整型p1;
无符号长整型p2;
};
向量表1=表1(n);/*更大的n->更多样本*/
向量表2=表2(n);/*n=10000每个表生成150k*/
向量常见;
for(无符号长整数i=0;i
是否有一种方法可以使用地图、设置或其他方法更快地完成此操作?
(我从c++开始)

事实上,您比较了它们之间的所有值,并希望知道每个集合中该值的键

在这种情况下,我建议简单地反转每个映射中的键和值。这将导致以下结构:

      Vals
RevKey1 RevVal1 RevKey2 RevVal2
4       1         5     1
6       2         9     2
8       4         4     4
10      6        10     6
然后,您只需迭代第一个映射,并在第二个映射中查找相同的键:

map<int,int> col1;
map<int,int> col2;
map<int,pair<int,int>> common ; 
...
for (auto& x: col1) {
    auto y= col2.find(x.first); 
    if (y!=col2.end()) 
        common[x.first]=make_pair(x.second,y->second);
}
cout<<"Result:"<<endl;
for (auto& x:common ) 
    cout << x.first << "<-" << x.second.first << " in col1 and " <<x.second.second << " in col2"<<endl;
map col1;
map-col2;
地图通用;
...
用于(自动和x:col1){
自动y=col2.find(x.first);
如果(y!=col2.end())
公共[x.first]=组成配对(x.second,y->second);
}

实际上,您比较了它们之间的所有值,并希望知道每个集合中该值的键

在这种情况下,我建议简单地反转每个映射中的键和值。这将导致以下结构:

      Vals
RevKey1 RevVal1 RevKey2 RevVal2
4       1         5     1
6       2         9     2
8       4         4     4
10      6        10     6
然后,您只需迭代第一个映射,并在第二个映射中查找相同的键:

map<int,int> col1;
map<int,int> col2;
map<int,pair<int,int>> common ; 
...
for (auto& x: col1) {
    auto y= col2.find(x.first); 
    if (y!=col2.end()) 
        common[x.first]=make_pair(x.second,y->second);
}
cout<<"Result:"<<endl;
for (auto& x:common ) 
    cout << x.first << "<-" << x.second.first << " in col1 and " <<x.second.second << " in col2"<<endl;
map col1;
map-col2;
地图通用;
...
用于(自动和x:col1){
自动y=col2.find(x.first);
如果(y!=col2.end())
公共[x.first]=组成配对(x.second,y->second);
}
cout下面(非常简单)的代码似乎可以解决问题:

#include <map>
#include <vector>
#include <iostream>

struct p
{
    p (int p1, int p2) : p1 (p1), p2 (p2) { }
    int p1;
    int p2;
};

std::vector<int> table1;
std::vector<int> table2;
std::vector<p> common;

#define N   100000

int main ()
{
    table1.reserve (N);
    table2.reserve (N);

    for (int i = 0; i < N; ++i)
        table1.emplace_back (rand ());

    for (int i = 0; i < N; ++i)
        table2.emplace_back (rand ());

    std::map <int, int> map1;
    for (int i = 0; i < N; ++i)
        map1 [table1 [i]] = i;

    common.reserve (N);

    int n = table2.size();
    for (int i = 0; i < n; i++)
    {
        auto f = map1.find (table2 [i]);
        if (f != map1.end ())
            common.emplace_back (i, f->second);
    }

    for (auto x : common)
       std::cout << x.p1 << ", " << x.p2 << "\n";
}
注意向量使用了
保留
安置_back

运行

我尝试将N增加到1000000,但仍然有效。无序(散列)映射可能更快。

以下(非常简单)代码似乎可以解决问题:

#include <map>
#include <vector>
#include <iostream>

struct p
{
    p (int p1, int p2) : p1 (p1), p2 (p2) { }
    int p1;
    int p2;
};

std::vector<int> table1;
std::vector<int> table2;
std::vector<p> common;

#define N   100000

int main ()
{
    table1.reserve (N);
    table2.reserve (N);

    for (int i = 0; i < N; ++i)
        table1.emplace_back (rand ());

    for (int i = 0; i < N; ++i)
        table2.emplace_back (rand ());

    std::map <int, int> map1;
    for (int i = 0; i < N; ++i)
        map1 [table1 [i]] = i;

    common.reserve (N);

    int n = table2.size();
    for (int i = 0; i < n; i++)
    {
        auto f = map1.find (table2 [i]);
        if (f != map1.end ())
            common.emplace_back (i, f->second);
    }

    for (auto x : common)
       std::cout << x.p1 << ", " << x.p2 << "\n";
}
注意向量使用了
保留
安置_back

运行


我尝试将N增加到1000000,但仍然有效。无序(散列)映射可能更快。

创建两个映射。A从键映射到列1,B从键映射到列2。然后只需比较A[key]==B[key]如果键同时存在,你的意思是用map代替vector?做同样的事情,在这种情况下,我不认为会更快,这个算法真的很慢……它应该是O(n lgn)而不是O(n^2)测试它,仍然非常慢…,比较映射或向量…。那么,你做得不对。正确的算法将同时迭代两个映射,而不是每次迭代第一个映射,然后检查第二个映射。这是错误的。你需要同时迭代两个映射。如果你仍然有问题,你可以你应该向你的老师寻求帮助,也就是给你这个作业的老师。这是老师的工作,帮助学生完成家庭作业。创建两个地图。A从键映射到列1,B从键映射到列2。然后只需比较A[键]==B[键]如果键同时存在,你的意思是用map代替vector?做同样的事情,在这种情况下,我不认为会更快,这个算法真的很慢……它应该是O(n lgn)而不是O(n^2)测试它,仍然非常慢…,比较映射或向量…。那么,你做得不对。正确的算法将同时迭代两个映射,而不是每次迭代第一个映射,然后检查第二个映射。这是错误的。你需要同时迭代两个映射。如果你仍然有问题,你可以你应该向你的老师寻求帮助,也就是给你这个作业的老师。这就是老师的工作,帮助学生完成家庭作业。为什么你需要两张地图?@PaulSanders我使用地图,因为OP有数据显示键不是连续的。例如,没有键3。使用
向量
你不能表示这一点。此外,OP建议数据可能不同于整数,这在地图中不是问题。对于您的answare,Thx似乎没有内置函数(考虑不同长度的表),这会更好,我知道如何反转贴图,但使用多重贴图对我来说是新的,这将是我的练习,Thx帮助:DWY你需要两个贴图吗?@PaulSanders我使用贴图,因为OP有数据显示键不是连续的。例如,没有键3。使用
向量
你不能表示这一点。此外,OP建议t数据可能不同于整数,这在映射中不是问题。对于您的answare,似乎没有内置函数(在不同长度的表中思考),这会更好,我知道如何反转映射,但使用multimap对我来说是新的,这将是我的练习,Thx帮助:D