【问题标题】:C++ STL Binary Search (lower_bound, upper_bound)C++ STL 二分搜索(lower_bound、upper_bound)
【发布时间】:2015-06-22 09:19:36
【问题描述】:

我已经实现了这样的二分搜索:

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

但它并不总能找到值。

这有什么问题?

【问题讨论】:

标签: c++ stl binary-search


【解决方案1】:

您的比较功能不适用于二分搜索。它不应该确定相等,它应该确定顺序关系。具体来说,如果第一个参数在排序范围内肯定在第二个之前,它应该返回 true。如果参数应该被认为是相等的,或者第二个在第一个之前,它应该返回 false。您的范围也需要按照相同的标准进行排序,才能使二分搜索起作用。

一个可能起作用的示例函数:

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;
}

一个类似的例子可以作为短路布尔评估的一课,如下所示:

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

两者都展示了一个名为strict weak ordering 的属性。标准库集合和搜索算法中的各种排序和/或搜索经常需要它。

又一个例子使用了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);
}

类似的算法可通过std::tie 用于元组。

当然,所有这些都假设您首先有一个实际的有序序列,按相同的比较逻辑排序。 (我们只能假设这是真的,因为没有发布任何证据)。

【讨论】:

  • @Barry Ben 很准确(像往常一样),只是简短。也许他等着吃晚饭=P(这件事发生在我身上)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多