比较它们之间的元素并获取共同值的键
Posted
技术标签:
【中文标题】比较它们之间的元素并获取共同值的键【英文标题】:Compare elements between them and get the keys of common values 【发布时间】:2018-09-26 22:31:45 【问题描述】:我在两个不同的集合中有成对的数据、键和值。我需要比较两个集合的值,并创建一个包含相等值的键对的集合。
例如,使用以下数据集:
Vals
Key Col1 Col2
1 4 5
2 6 9
4 8 4
6 10 10
常见的值是 4 和 10。所以他的想法是用这些对获得一个新集合,在这种情况下是 (key col1, key col2) 1, 4, 6, 6
我需要一种最快的方法来做到这一点,每个集合可以有 100k 的数据,并且使用 for 循环进行迭代太慢,我尝试使用向量。
两个集合不一定有相同的键(如 map),数据可能不是 int (我使用二进制数据,通常键是 int(unsinged long)。
这是我的示例代码(非常慢的代码):
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++ 开始)
【问题讨论】:
创建两张地图。 A 从键映射到 col1,B 从键映射到 col2。然后只比较 A[key] == B[key] 如果 key 存在于两者中 你的意思是用map而不是vector做同样的事情?,在那种情况下我认为不会更快,这个算法真的很慢...... 应该是 O(n lgn) 而不是 O(n^2) 测试了一下,还是很慢...,比较地图或者矢量图..... 那你做得不对。正确的算法将同时遍历两个映射,而不是遍历第一个映射,然后每次都检查第二个映射。这是错误的。您需要同时遍历两个地图。如果你还有问题,你应该向你的老师寻求帮助,也就是给你这个作业的那个人。这就是教师的报酬,帮助学生完成家庭作业。 【参考方案1】:实际上,您比较了它们之间的所有值,并想知道每个集合中该值的键。
在这种情况下,我建议简单地反转每个映射中的键和值。这将导致以下结构:
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;
Online demo
备注:我让您作为练习,对现有地图中表达的映射关系进行反演。我还让你扩展这个算法来处理多映射,以防多个键具有相同的值。
【讨论】:
为什么需要两张地图? @PaulSanders 我使用了地图,因为 OP 的数据显示键不连续。例如没有键 3。使用vector<int>
你不能代表这个。此外,OP 建议数据可能与整数不同,这在地图的情况下不是问题。
感谢您的回答,似乎没有内置函数(考虑不同长度的表),这会更好,我知道如何反转地图,但使用 multimap 是对我来说是新的,那将是我的练习,谢谢帮助:D【参考方案2】:
下面的(非常简单的)代码似乎可以解决问题:
#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,但它仍然有效。无序(散列)地图可能会更快。
【讨论】:
以上是关于比较它们之间的元素并获取共同值的键的主要内容,如果未能解决你的问题,请参考以下文章