简体   繁体   English

C ++ STL二进制搜索(lower_bound,upper_bound)

[英]C++ STL Binary Search (lower_bound, upper_bound)

I have implemented a binary search like this: 我已经实现了这样的二进制搜索:

typedef std::vector<Cell>::iterator CellVectorIterator;

typedef struct _Point {
    char x,y;
} CoordinatePoint;

typedef struct _Cell {
    ...
    CoordinatePoint coordinates;
} Cell;

struct CellEqualityByCoordinates
{
    bool
    operator()(const Cell& cell1, const Cell& cell2) const
    { return cell1.coordinates.x == cell2.coordinates.x && cell1.coordinates.y == cell2.coordinates.y; }
};

CellVectorIterator FindCellByCoordinates (CellVectorIterator first, CellVectorIterator last, const Cell &val)
{
    return std::upper_bound(first, last, val, CellEqualityByCoordinates());
}

But it doesn't always find a value. 但是,它并不总能找到价值。

What's wrong with that? 怎么了

Your comparison function will not work for a binary search. 您的比较功能不适用于二进制搜索。 It is not supposed to determine equality, it is supposed to determine an order relation. 它不应该确定相等性,它应该确定顺序关系。 Specifically, it should return true if the first argument would definitively come before the second in a sorted range. 具体来说,如果第一个参数在排序范围内肯定要排在第二个参数之前,则应返回true。 If the arguments should be considered equal, or the second would come before the first, it should return false. 如果参数应视为相等,或者第二个参数在第一个参数之前,则应返回false。 Your range also needs to be sorted by this same criteria in order for the binary search to work. 您的范围也需要按照相同的条件进行排序,以便二进制搜索正常工作。

An example function that might work: 可能起作用的示例函数:

bool operator()(const Cell& cell1, const Cell& cell2) const 
{
    if (cell1.coordinates.x < cell2.coordinates.x) return true;
    if (cell2.coordinates.x < cell1.coordinates.x) return false;
    return cell1.coordinates.y < cell2.coordinates.y;
}

A similar example that doubles as a lesson in short-circuit boolean evaluation would be something like: 在短路布尔值评估中加倍作为教训的类似示例将是:

bool operator()(const Cell& cell1, const Cell& cell2) const 
{
    return (cell1.coordinates.x < cell2.coordinates.x) ||
        (!(cell2.coordinates.x < cell1.coordinates.x) &&
          cell1.coordinates.y < cell2.coordinates.y);
}

Both exhibit a property called strict weak ordering . 两者都具有称为严格弱序的属性。 It is frequently required for various sorting and/or searches in standard library collections and search algorithms. 在标准库集合和搜索算法中经常需要进行各种排序和/或搜索。

Yet another example utilizes a std::pair , which already has a proper std::less overload available that does the above, and thus makes this considerably less complicated: 另一个示例利用std::pair ,该对象已经具有适当的std::less重载,可以执行上述操作,因此使此操作复杂度大大降低:

bool operator()(const Cell& cell1, const Cell& cell2) const
{
    return std::make_pair(cell1.coordinates.x, cell1.coordinates.y) <
           std::make_pair(cell2.coordinates.x, cell2.coordinates.y);
}

A similar algorithm is available for tuples via std::tie . 可通过std::tie为元组提供类似的算法。

Of course, all of this assumes you have an actual ordered sequence in the first place, ordered by the same comparison logic. 当然,所有这些都假定您首先具有一个实际的有序序列,并由相同的比较逻辑进行排序。 (which we can only assume is true, as no evidence of such was posted). (我们只能假设它是真实的,因为没有发布任何此类证据)。

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

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