我在两个不同的集合中有一对数据,键和值。我需要比较两个集合的值,并创建一个包含值相等的键对的集合。
例如,具有以下数据集:
Vals
Key Col1 Col2
1 4 5
2 6 9
4 8 4
6 10 10
公共值将是4和10。因此,他的想法是得到一个带有对的新集合,在这种情况下(键col1,键col2){{1,4},{6,6}}
我需要一种最快的方法来执行此操作,每个集合都可以容纳大约100k的数据,而使用for循环进行迭代太慢了,我尝试使用vector。
两个集合不一定都具有相同的键(如map),并且数据可能不是int(我使用二进制数据,并且通常这些键都是int(长整型))。
这是我的示例代码(非常慢的代码):
struct p {
unsigned long int p1;
unsigned long int p2;
};
vector<int> table1 = tables1(n); /* bigger n -> more samples */
vector<int> table2 = tables2(n); /* n = 10000 generate 150k per table */
vector<p> common;
for (unsigned long int i = 0;i < table1.size(); i++) {
for (unsigned long int j = 0; j < table2.size(); j++) {
if (table1[i] == table2[j]) {common.push_back ({i, j};}
}
}
是否可以通过地图,设置或某种方式更快地完成此任务? (我从c ++开始)
答案 0 :(得分:2)
实际上,您比较了它们之间的所有值,并想知道每个集合中该值的键。
在这种情况下,我建议您简单地反转每个映射中的键和值。这将导致以下问题:
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;
备注:作为练习,我将反转现有地图中表示的映射关系。如果多个键具有相同的值,我还可以扩展该算法以应对多图。
答案 1 :(得分:0)
以下(非常简单的)代码似乎割了芥末酱:
#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";
}
输出:
12727, 93810
12766, 48493
16044, 71990
43202, 35849
46218, 81007
82512, 70112
98740, 72244
请注意对向量使用reserve
和emplace_back
。
在Wandbox上运行它
我尝试将N增加到1000000,但它仍然有效。无序(散列)的地图可能会更快。