在std :: vector中进行二进制搜索

时间:2016-05-12 10:44:04

标签: c++ vector std binary-search

我试图将矢量元素的位置寻找到另一个矢量中。在这里,我有兴趣使用与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;
}  

我想知道代码是否与二进制搜索实现匹配。??

是否有更快的方法来获取向量元素的索引?

有关改进此代码的任何进一步建议。

3 个答案:

答案 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的beginend而不是调用仅用于包装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