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