C++ 数对的有效搜索
我有一个问题,我有一个大的数字对列表。诸如此类:C++ 数对的有效搜索,c++,algorithm,C++,Algorithm,我有一个问题,我有一个大的数字对列表。诸如此类: (0, 1) (10, 5) (5, 6) (8, 6) (7, 5) ..... 我需要做的是,如果列表中存在一对,我可以快速查找。 我的第一个想法是制作映射容器。并使用container.find()进行搜索 第二个想法是使vector如果您不关心插入,那么可以使用排序的std::vector和std::binary\u搜索,或者std::lower\u界限 int main() { using namespace std;
(0, 1)
(10, 5)
(5, 6)
(8, 6)
(7, 5)
.....
我需要做的是,如果列表中存在一对,我可以快速查找。
我的第一个想法是制作映射
容器。并使用container.find()
进行搜索
第二个想法是使
vector如果您不关心插入,那么可以使用排序的std::vector和std::binary\u搜索,或者std::lower\u界限
int main()
{
using namespace std;
vector<pair<int, int>> pairs;
pairs.push_back(make_pair(1, 1));
pairs.push_back(make_pair(3, 1));
pairs.push_back(make_pair(3, 2));
pairs.push_back(make_pair(4, 1));
auto compare = [](const pair<int, int>& lh, const pair<int, int>& rh)
{
return lh.first != rh.first ?
lh.first < rh.first : lh.second < rh.second;
};
sort(begin(pairs), end(pairs), compare);
auto lookup = make_pair(3, 1);
bool has31 = binary_search(begin(pairs), end(pairs), lookup, compare);
auto iter31 = lower_bound(begin(pairs), end(pairs), lookup, compare);
if (iter31 != end(pairs) && *iter31 == lookup)
cout << iter31->first << "; " << iter31->second << "at position "
<< distance(begin(pairs), iter31);
}
intmain()
{
使用名称空间std;
向量对;
配对。推回(使配对(1,1));
成对。向后推(形成成对(3,1));
成对。向后推(形成成对(3,2));
成对。向后推(形成成对(4,1));
自动比较=[](常数对和左侧、常数对和右侧)
{
返回左侧优先!=右侧优先?
左第一<右第一:左第二<右第二;
};
排序(开始(对)、结束(对)、比较);
自动查找=生成一对(3,1);
bool has31=二进制搜索(开始(对)、结束(对)、查找、比较);
自动iter31=下限(开始(对)、结束(对)、查找、比较);
if(iter31!=结束(对)&&*iter31==查找)
cout first如果不关心插入,可以使用排序的std::vector和std::binary\u搜索,或std::lower\u界限
int main()
{
using namespace std;
vector<pair<int, int>> pairs;
pairs.push_back(make_pair(1, 1));
pairs.push_back(make_pair(3, 1));
pairs.push_back(make_pair(3, 2));
pairs.push_back(make_pair(4, 1));
auto compare = [](const pair<int, int>& lh, const pair<int, int>& rh)
{
return lh.first != rh.first ?
lh.first < rh.first : lh.second < rh.second;
};
sort(begin(pairs), end(pairs), compare);
auto lookup = make_pair(3, 1);
bool has31 = binary_search(begin(pairs), end(pairs), lookup, compare);
auto iter31 = lower_bound(begin(pairs), end(pairs), lookup, compare);
if (iter31 != end(pairs) && *iter31 == lookup)
cout << iter31->first << "; " << iter31->second << "at position "
<< distance(begin(pairs), iter31);
}
intmain()
{
使用名称空间std;
向量对;
配对。推回(使配对(1,1));
成对。向后推(形成成对(3,1));
成对。向后推(形成成对(3,2));
成对。向后推(形成成对(4,1));
自动比较=[](常数对和左侧、常数对和右侧)
{
返回左侧优先!=右侧优先?
左第一<右第一:左第二<右第二;
};
排序(开始(对)、结束(对)、比较);
自动查找=生成一对(3,1);
bool has31=二进制搜索(开始(对)、结束(对)、查找、比较);
自动iter31=下限(开始(对)、结束(对)、查找、比较);
if(iter31!=结束(对)&&*iter31==查找)
cout firststd::set
可能是一种方法,即使元素数量增加,它的性能也应该相当好(而std::vector
的性能会很快降低,除非您事先对其进行排序并进行某种二进制或树搜索)。请记住,您必须定义一个std::set
可能是一种方法,即使元素数量增加,它也应该表现得相当好(而std::vector
的性能会很快降低,除非您事先对其进行排序并进行某种二进制或树搜索)。请记住,您必须定义一个为什么不根据第一个元素对元组进行排序,然后第二个,然后二进制搜索应该是O(log(n))。为什么不根据第一个元素对元组进行排序,然后第二个,然后二进制搜索应该是O(log(n))。您可以使用哈希集的一些实现来更快地进行排序
例如,boost::unordered_set,其中键是std::pair。
这是最简单的方法中最快的方法。您可以使用哈希集的一些实现来加快速度
例如,boost::unordered_set,其中键是std::pair。
这是最简单的方法中最快的方法。如果您希望比设置查找快(比O(lg n)
快),并且不关心项目的随机顺序,那么哈希表就是最好的选择
这不是标准的一部分,但是大多数编译器中都有一个散列集
如果您想进行真正的快速搜索,您可以尝试。但是,它们有时会导致误报(即,在没有项目对的情况下检测到有项目对),并且需要大量内存。合适的Bloom筛选器实现可能是:
const int MAX_HASH = 23879519; // note it's prime; must be 2-5 times larger than number of your pairs
vector<bool> Bloom(MAX_HASH); // vector<bool> compresses bools into bits
// multiply one by a large-ish prime, add the second, return modulo another prime
// then use it as the key for the filter
int hash(long long a, long long b) {
return (a*15485863LL + b) % MAX_HASH;
}
// constant-time addition
void add_item(pair<int,int> p) {
Bloom[hash(p.first, p.second)] = true;
}
// constant-time check
bool is_in_set(pair<int,int> p) {
return Bloom[hash(p.first, p.second)];
}
const int MAX_HASH=23879519;//注意它是素数;必须比成对数大2-5倍
向量Bloom(MAX_HASH);//向量将布尔压缩为位
//用一个大素数乘以一个大素数,再加上第二个,返回另一个素数的模
//然后将其用作过滤器的键
int散列(长a、长b){
返回(a*15485863LL+b)%MAX\u散列;
}
//恒定时间加法
无效添加项(对p){
Bloom[hash(p.first,p.second)]=true;
}
//定时检查
布尔值在集合中(对p){
返回Bloom[hash(p.first,p.second)];
}
如果您希望比设置查找快(比O(lg n)
快),并且不关心项目的随机顺序,那么哈希表就是一种方法
这不是标准的一部分,但是大多数编译器中都有一个散列集
如果您想进行真正的快速搜索,您可以尝试。但是,它们有时会导致误报(即,在没有项目对的情况下检测到有项目对),并且需要大量内存。合适的Bloom筛选器实现可能是:
const int MAX_HASH = 23879519; // note it's prime; must be 2-5 times larger than number of your pairs
vector<bool> Bloom(MAX_HASH); // vector<bool> compresses bools into bits
// multiply one by a large-ish prime, add the second, return modulo another prime
// then use it as the key for the filter
int hash(long long a, long long b) {
return (a*15485863LL + b) % MAX_HASH;
}
// constant-time addition
void add_item(pair<int,int> p) {
Bloom[hash(p.first, p.second)] = true;
}
// constant-time check
bool is_in_set(pair<int,int> p) {
return Bloom[hash(p.first, p.second)];
}
const int MAX_HASH=23879519;//注意它是素数;必须比成对数大2-5倍
向量Bloom(MAX_HASH);//向量将布尔压缩为位
//用一个大素数乘以一个大素数,再加上第二个,返回另一个素数的模
//然后将其用作过滤器的键
int散列(长a、长b){
返回(a*15485863LL+b)%MAX\u散列;
}
//恒定时间加法
无效添加项(对p){
Bloom[hash(p.first,p.second)]=true;
}
//定时检查
布尔值在集合中(对p){
返回Bloom[hash(p.first,p.second)];
}
如果您的单个数字是int
s,这里有另一个解决方案
用两个int
s构建一个long
(第一个int
可以是高32位,第二个int
可以是低32位)
将其插入到无序集
(或集
,或排序的向量
-配置文件中以查找匹配项)
找到
应该比工作快一些