关于标准::binary_search()的查询

Inquiry on std::binary_search()

本文关键字:search 查询 binary 标准 于标准      更新时间:2023-10-16

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

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

[first, last)

那么它不包括最后一个,因为它必须将最后一个与最后一个 + 1 进行比较吗?

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

例如,如果我的结构/类由以下内容组成:

coord
{
    int X;
    int Y;
}

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

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

那么它不包括最后一个,因为它必须将最后一个与最后一个 + 1 进行比较吗?

不,原因只是为了方便使用。您可以按以下方式调用该函数:

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

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

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

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

对于您的坐标示例,您可以编写一个比较器函数,如下所示:

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());

该范围不包括最后一个元素作为一般库约定,这意味着第一个最后一个迭代器之间的距离等于该范围内的元素数,并且可以使用以下命令在循环中测试该范围:

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

必须对使用相同(可能是用户定义的)比较函数排序的排序数据执行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
}

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