我有以下向量:
std::vector<A*> vec;
std::vector<std::pair<A*, A*>> vec_pair;
vec_pair的大小远远大于vec的大小。我想在vec_pair中找到一对,其中两个成员都在vec内部。
vec_pair
的内容是不变的。但是,每次迭代后,vec
的内容都会发生变化,我想再次进行测试。
我知道我可以做一个for循环并做检查。但是考虑到尺寸差异和工作的重现,我正在寻找一种智能且高效的方法。
答案 0 :(得分:3)
如果您不打算更改vec
的内容,请创建具有相同内容的std::unordered_set<A*>
并搜索其中的匹配项。在unordered_set
中搜索大约为O(1),因此这将是一个简单的胜利。
从unordered_set
构造vector
的最简单,最有效的方法是使用带有两个迭代器的构造函数:
unordered_set<A*> us(vec.begin(), vec.end());
答案 1 :(得分:2)
vec_pair
尺寸大于vec
尺寸。
这应该作为线索使用std::map
。
将向量vec
的所有元素放在地图中:myMap[vec[i]] = 1;
然后浏览vec_pair
中的每一对,然后执行
if (myMap.find(vec_pair[i].first != myMap.end()) &&
myMap.find(vec_pair[i].second != myMap.end()) )
{
return FOUND;
}
else
return NOT_FOUND;`
如盖茨评论,请使用unordered_map
来加快操作速度。
答案 2 :(得分:2)
您可以使用unordered_set
(您真的不需要map
),这允许O(1)
搜索和插入
1)从vec开始构建unordered_set<A*> S;
2)对于vec_pair
中的每一对,您可以检查S
以下内容将平均O(vec_pair.size())
std::vector<A*> vec;
std::vector<std::pair<A*, A*>> vec_pair;
unordered_set<A*> S;
for(auto a: vec)
S.insert(a);
for(auto p : vec_pair){
if(s.find(p.first)!=S.end() &&
s.find(p.second)!=S.end())
{
//PAIR GOOD
}else{
//THIS PAIR IS NOT GOOD
}
}
答案 3 :(得分:1)
我不知道你的确切要求但是,如果vec_pair
中元素的顺序不重要,我想你可以用std::multimap
代替它,或者我想更好,{ {1}}。
我的意思是(使用等于std::unordered_multimap
的{{1}}类型代替)
A
你可以使用
int
如果您需要 using A = int;
std::vector<std::pair<A, A>> const vec_pair
{ {1, 1}, {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 2}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 3}, {3, 4},
{4, 1}, {4, 2}, {4, 3}, {4, 4} };
是对的向量,使用 std::unordered_multimap<A, A> const cM
{ {1, 1}, {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 2}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 3}, {3, 4},
{4, 1}, {4, 2}, {4, 3}, {4, 4} };
是常量的事实(我理解正确吗?),您可以构造一个常量无序多图。
此解决方案的优点是,如果您发现地图的某个键不在vec_pair
中,则可以避免使用相同的键对所有值进行测试。
更多:如果从vec_pair
开始构建vec
(或更好,set
)(这很少,如果我理解正确,您可以按以下方式检查对< / p>
unordered_set
我知道:这不是一个优雅的解决方案。
另一种方法是使用map和set(unorderd,better)的组合而不是
vec
使用(或构建)
for ( auto ci = cM.cbegin() ; ci != cM.cend() ; )
{
auto val = ci->first;
auto cnt = cM.count(val);
if ( s.end() == s.find(val) )
{
for ( auto i = 0U ; i < cnt ; ++i )
++ci;
}
else for ( auto i = 0U ; i < cnt ; ++i, ++ci )
if ( s.end() != s.find(ci->second) )
std::cout << "- good for <" << val << ", " << ci->second
<< '>' << std::endl;
}
在这种情况下,搜索部分更优雅(恕我直言)
std::vector<std::pair<A, A>> const vec_pair
{ {1, 1}, {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 2}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 3}, {3, 4},
{4, 1}, {4, 2}, {4, 3}, {4, 4} };
以下是两种解决方案的完整可编辑示例
std::unordered_map<A, std::unordered_set<A>> const cM
{ {1, {1, 2, 3, 4}}, {2, {1, 2, 3, 4}},
{3, {1, 2, 3, 4}}, {4, {1, 2, 3, 4}} };
答案 4 :(得分:0)
vec比vec_pair小多少? vec大小的平方是否仍然小于vec_pair的大小?如果是这样,你从vec_pair中创建一个unordered_set,然后搜索从vec中的两个东西生成的每个可能的对。
为什么不能对这两个容器进行排序?你可以制作每个的分类副本吗?如果是这样,请指向两个列表的开头,并增加两个匹配项。你仍然是O(vec_pair的大小),但你的常数会很小 - 通常只是一个指针比较。