我想执行两个大键值列表的传递闭包。为此,我有两个" std :: map"。 std :: map都将整数映射到整数向量。
std::map<unsigned,vector<unsigned> > mapIntVecOfInts1;
std::map<unsigned,vector<unsigned> > mapIntVecOfInts2;
&#34; mapIntVecOfInts1&#34;将键映射到另一组键(VALUES)。其中的一些示例值具有以下形式:
0 -> (101, 102, 201)
1 -> (101, 102, 103, 203, 817, 1673)
2 -> (201, 829, 858, 1673)
&#34; mapIntVecOfInts2&#34;映射&#34; mapIntVecOfInts1&#34;中存在的VALUES;到另一组价值观。例如
101 -> (4002, 8293, 9000)
102 -> (4002, 8293, 10928)
103 -> (8293, 10928, 19283, 39201)
201 -> (8293)
203 -> (9393, 9830)
817 -> (19393, 19830)
1673-> (5372, 6830)
现在我要映射&#34; mapIntVecOfInts1&#34;中存在的键。到#34; mapIntVecOfInts2&#34;中出现的值使用来自&#34; mapIntVecOfInts1&#34;的传递映射; to&#34; mapIntVecOfInts2&#34;。例如。我想为关键&#34; 0&#34;做以下事情。 mapIntVecOfInts1:
0 -> 4002, 9000, 10928, 8293, 19283, 39201
1 -> 4002, 8293, 9000, 10928, 19283, 39201, 9393, 9830, 19393, 19830, 5372, 6830
&#34; mapIntVecOfInts1&#34;和&#34; mapIntVecOfInts2&#34;包含十亿个元素(键)。两个映射中的向量本身包含百万个无符号整数。我尝试通过存储&#34; mapIntVecOfInts1&#34;来实现两个地图之间的这种传递闭包。和&#34; mapIntVecOfInts2&#34;在记忆中。使用以下代码:
std::vector<unsigned,vector<unsigned> > result;
for(std::map<unsigned,vector<unsigned> >::iterator i1= mapIntVecOfInts1.begin(), l1=mapIntVecOfInts1.end(); i1!=l1;++i1)
{
vector<unsigned> vec1;
for(vector<unsigned>::iterator i2=(*i1).second.begin(), l2=(*i1).second.end(); i2!=l2; ++i2)
vec1.insert(vec1.begin(), mapIntVecOfInts2[*i2].begin(), mapIntVecOfInts2[*i2].end());
result.push_back(make_pair((*i1).first, vec1));
}
然而,以这种方式执行传递闭包需要花费很多时间。有什么方法可以加快这个速度。
答案 0 :(得分:2)
可以说你建议的代码做了两件事:
生成的映射将具有与第一个关系完全相同的键集,因此您可以(通过先复制整个mapIntVecOfInts1
然后修改值来避免整个红黑树构建过程)副本而不是逐个添加向量。
当然,这不会解决主要的瓶颈,即第二关系的访问速度(mapIntVecOfInts2)。您可以尝试使用哈希表(std::unordered_map
)将其减少为摊销的O(1),或者如果您的&#34;十亿的键&#34;不是太稀疏。
同样@SpectralSequence说,你的代码不保留值向量中的唯一性,也许你想对此做些什么。
答案 1 :(得分:1)
至少,你应该在内部循环中插入向量的末尾,因为在开头插入需要复制已经在向量中的元素。
vec1.insert(vec1.end(), mapIntVecOfInts2[*i2].begin(), mapIntVecOfInts2[*i2].end());
此外,如果您不想要重复值,请考虑使用集合。