我试图将矢量元素的位置寻找到另一个矢量中。在这里,我有兴趣使用与binary search
一样快的实现。我有不同的长度为100万或更多的向量,所以我想要更快地实现某些目标。
以下情况:
我正在搜索的 1) vector
已排序。
2)我正在搜索的元素将永远存在,即我没有not found
的情况,我想得到矢量元素的索引以更快的方式。
我尝试使用以下代码来获取向量元素的索引。
#include <iostream>
#include <vector>
#include <algorithm>
template<class Iter, class T>
Iter binary_find(Iter begin, Iter end, T val)
{
Iter i = std::lower_bound(begin, end, val);
return i;
}
int main() {
std::vector<std::string> values = {"AAAAAA","AB", "AD" ,"BCD","CD", "DD" };
std::vector<std::string> tests = {"AB", "CD","AD", "DD"};
for(int i=0 ; i < tests.size(); i++) {
int pos = binary_find(values.begin(), values.end(), tests.at(i))- values.begin();
std::cout << tests.at(i) << " found at: " << pos <<std::endl;
}
return 0;
}
我想知道代码是否与二进制搜索实现匹配。??
是否有更快的方法来获取向量元素的索引?
有关改进此代码的任何进一步建议。
答案 0 :(得分:4)
binary_find
虽然未声明返回void
,但未返回任何内容,因此它具有未定义的行为。
修复后,假设你没有对矢量内容的具体了解,除了它的排序,二元搜索是非常优化的。
然而,对于基于谓词的查找而言,其他数据结构比向量更快。如果性能至关重要,您应该查看搜索树和哈希映射。由于您的键是字符串,因此特别是尝试和定向非循环字图可能是有效的。您可能希望衡量哪种方法最适合您的用例。
答案 1 :(得分:2)
http://www.cpluplus.com表示binary_search
的行为等同于:
template <class ForwardIterator, class T>
bool binary_search (ForwardIterator first, ForwardIterator last, const T& val) {
first = std::lower_bound(first, last, val);
return (first != last && !(val < *first));
}
是的,lower_bound
是您的首选武器。但是当你采取差异时,你应该使用distance
。因为,如果有更快的方式来获取该位置,它将被转入该函数。
就其他改进而言,我建议使用C ++ 14的begin
和end
而不是调用仅用于包装lower_bound
的函数(并且不能正确使用)返回一个值。)所以我编写这段代码的方式如下:
auto pos = distance(lower_bound(begin(values), end(values), tests[i]), begin(values));
答案 2 :(得分:1)
Q1:我想知道代码是否与二进制搜索实现匹配。??
是,它(almost)是。查看std::lower_bound,其中说明:
复杂度:
平均而言,第一和第二之间的距离是对数 last:执行大约log2(N)+1个元素比较(其中N是 这个距离)。在非随机访问迭代器上,迭代器前进 在平均N中产生额外的线性复杂度。
Q2:是否有更快的方法来获取向量元素的索引。??
这是一个相当广泛的问题。
问题3:任何进一步改进此代码的建议。
Hello world,Code Review!
PS - 您是否编译过代码?它提供了几条消息,例如:
warning: no return statement in function returning non-void [-Wreturn-type]
编译并启用警告,如下所示:
g++ -Wall main.cpp