在C 中的大量向量中搜索
Search within a big vector in C++
我有以下向量:
std::vector<A*> vec;
std::vector<std::pair<A*, A*>> vec_pair;
vec_pair尺寸远远超过VEC尺寸。我想在VEC_PAIR中找到两个成员在VEC中的一对。
vec_pair
的内容是恒定的。但是,在每次迭代之后,vec
的内容都会改变,我想再次进行测试。
我知道我可以做一个循环并进行检查。但是,考虑大小差异和作业的复发,我正在寻找一种智能有效的方法来完成。
如果您不要更改vec
的内容,请创建一个具有相同内容的std::unordered_set<A*>
并在那里搜索出现。在unordered_set
中搜索大约是O(1(,因此这将是一个简单的胜利。
从vector
构造unordered_set
的最简单和最有效的方法是使用构造函数,采用两个迭代器:
unordered_set<A*> us(vec.begin(), vec.end());
您可以使用unordered_set
(您实际上不需要map
(,该O(1)
search 和 insert 。>
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
}
}
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
进行更快的操作。
我不知道您的确切要求,但是,如果vec_pair
中的元素顺序并不重要,我想您可以用std::multimap
替换它,或者我想更好的是std::unordered_multimap
。
我的意思是(使用等于 int
的类型A
(
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
(或者更好,是unordered_set
(,请从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;
}
我知道:不是优雅的解决方案。
另一种方法是使用地图和设置的组合(unorderd,更好(,而不是
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}} };
在这种情况下,搜索部分更优雅(IMHO(
for ( auto const & p : cM2 )
if ( s.end() != s.find(p.first) )
for ( auto const & sec : p.second )
if ( s.end() != s.find(sec) )
std::cout << "- good for <" << p.first << ", " << sec
<< '>' << std::endl;
以下是两个解决方案的完整汇编示例
#include <vector>
#include <utility>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
int main()
{
using A = int;
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} };
std::unordered_set<A> s { 4, 3 };
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::unordered_map<A, std::unordered_set<A>> const cM2
{ {1, {1, 2, 3, 4}}, {2, {1, 2, 3, 4}},
{3, {1, 2, 3, 4}}, {4, {1, 2, 3, 4}} };
for ( auto const & p : cM2 )
if ( s.end() != s.find(p.first) )
for ( auto const & sec : p.second )
if ( s.end() != s.find(sec) )
std::cout << "- good for <" << p.first << ", " << sec
<< '>' << std::endl;
}
VEC比VEC_PAIR小多少?VEC大小的平方仍然比VEC_PAIR的大小小吗?如果是这样,您可以从vec_pair中制作一个unordered_set,然后搜索从VEC中生成的每对可能的对。
为什么不能对两个容器进行排序?您可以制作每个分类的副本吗?如果是这样,请将指针指向两个列表的开始,并增加寻找匹配项。您仍然会是O(vec_pair的大小(,但是您的常数确实很小 - 通常只是一个指针比较。
- 向量上的线性搜索
- 对的排序向量 (std::vector<pair<int, int>>) 按对的第一个元素搜索并更新第二个元素值
- 哪个更快:在 1d 向量中按字符串搜索还是在 2d 向量中按向量搜索?
- C++:使用类在向量中搜索特定元素时,我得到了错误的结果
- 搜索并替换结构向量中的值
- 我可以做些什么来改进指针向量中的此搜索?
- 迭代向量以获得搜索功能
- 有没有办法搜索向量的元素,<String>然后检查它是否包含特定的字符,如果它确实打印了它
- 如何二进制搜索结构向量并在适当的索引处插入
- 按类型排序向量并按类型或派生类型搜索
- 如何在 c++ 中对两个向量进行线性搜索?
- 从整数向量向量搜索整数向量的最佳算法
- 在结构向量中搜索一个数据成员,然后打印匹配的所有数据成员
- 用户输入字符串的结构的搜索向量
- 如何在向量上进行二进制搜索以找到具有特定id的元素
- 如何在使用和无发现的情况下使用和不使用的字符串向量搜索元素
- 如何通过对象向量搜索匹配项
- 使用C++-AMP来减少未排序向量搜索的运行时间
- 通过 unique_ptr 的向量搜索的查找函数的返回值
- 对象的向量搜索未来对象的使用?