繁体   English   中英

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

[英]Binary search in std::vector

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

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

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

任何进一步的建议,以改善此代码。

尽管未声明返回 voidbinary_find不会返回任何内容,因此它具有未定义的行为。

\n

在它被修复之后,并且 假设你没有关于向量的内容的特定知识而不是它被排序,二进制搜索是非常优化的。

但是,对于基于谓词的查找,其他数据结构比向量更快。 如果性能至关重要,您应该查看搜索树和哈希映射。 由于您的键是字符串,因此特别是尝试和定向非循环字图可能是有效的。 您可能想要衡量哪个最适合您的用例。

http://www.cpluplus.combinary_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));

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

是的 ,它( 几乎 )是。 检查std :: lower_bound ,其中指出:

复杂:

平均而言,第一个和最后一个之间距离的对数:执行大约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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM