查询std :: binary_search()

时间:2016-02-26 02:06:19

标签: c++ list indexing compare binary-search

我目前正在考虑使用std :: binary_search()(来自库)来确定列表中是否存在某个实例。我想在开始使用它之前知道它是如何工作的。

我的理解是它使用比较(对于用户定义的结构/类,它需要访问用户定义的比较函数)来查明对象的实例是否存在于列表/向量中。根据该网站(http://www.cplusplus.com/reference/algorithm/binary_search/),使用的范围是:

[first, last)

因此,它不是包括 最后,因为它必须将最后最后+ 1 进行比较?< / p>

用户定义的比较函数的逻辑也无关紧要,只要它区分对象/类中的属性即可。这是对的吗?

例如,如果我的struct / class由以下内容组成:

coord
{
    int X;
    int Y;
}

我必须确保我的比较函数区分(以某种方式,例如大于/小于比较)列表/向量中元素a和b的X和Y属性。

2 个答案:

答案 0 :(得分:2)

std :: binary_search()作为常见的二进制搜索算法实现,它最多执行log2(N)+1个元素比较。 (有关如何实现二进制搜索的更多信息,请查看此link

  

所以它不包括最后一个因为它必须比较最后一个+ 1?

不,原因只是为了方便其使用。您可以将该功能称为:

std::binary_search (v.begin(), v.end(), 42)

请注意,v.end()返回超过序列末尾的元素的迭代器。因此,它不指向任何元素,因此不应在搜索中进行评估。

  

用户定义的比较函数的逻辑也无关紧要,只要它区分对象/类中的属性即可。这是对的吗?

它用于binary_search()的比较函数,以便知道您要查找的元素是否在当前正在测试的元素之后。换句话说,比较函数必须能够比较两个元素并返回第一个元素是&#34;更低&#34;比第二个(必须在第二个之前放在容器中)。

对于您的Coord示例,您可以编写比较器函数,如:

struct lessThanKey
{
    inline bool operator() (const Coord& lhs, const Coord& rhs)
    {
        return (lhs.x < rhs.x) || ((lhs.x == rhs.x) && (lhs.y < rhs.y));
    }
};

std::binary_search(v.begin(), v.end(), Coord{42, 42}, lessThanKey());

答案 1 :(得分:1)

范围包含 last 元素作为常规库约定,它意味着 first 之间的距离最后迭代器等于范围内元素的数量,并且可以使用以下方法在循环中测试范围:

while(first != last)
{
    // process stuff
    ++first;
}

必须对使用相同(可能是用户定义的) compare 函数排序的排序数据执行std::binary_search

该函数需要在两个元素之间建立小于的关系。

struct coord
{
    int x;
    int y;
};

struct CoordComparator
{
    bool operator()(const coord& lhs, const coord& rhs) const
    {
        return lhs.x == rhs.x ? lhs.y < rhs.y : lhs.x < rhs.x;
    }
};

std::vector<coord> v { {1, 1}, {2, 1}, {2, 2}, {1, 2} };

std::sort(v.begin(), v.end(), CoordComparator());

if(std::binary_search(v.begin(), v.end(), coord{2, 1}, CoordComparator()))
{
    // element found in range
}

可以定义小于的关系,以便更大的值报告小于更低的值,以提供反向排序关系。