如何找到距离大于19.0f的排序列表中的第一个元素?

时间:2012-10-20 10:02:51

标签: c++ algorithm stl

在std :: pair的排序列表中,按原点的距离按升序排序

pair<float,float> origin;
list<pair<float,float> > points;
float distance=19.0f;

如何找到距离大于距离(19.0f)的列表中的第一个元素? 如何申请列表二进制搜索? (迭代效率不高,列表很长)? 有更优雅的解决方案吗?

6 个答案:

答案 0 :(得分:3)

列表不适合二进制搜索。这是因为您只能访问列表中的元素顺序(您只能从元素k访问元素k-1),因此如果您必须使用列表,除了线性搜索大于distance的第一个元素之外别无选择。

如果您想进行二进制搜索,可以使用允许直接访问元素的vector等容器(如myvector[i]中所述)

答案 1 :(得分:2)

您不能在链接列表上进行二进制搜索。请考虑将其替换为vectormultiset

答案 2 :(得分:2)

您无法有效地对链接列表执行二进制搜索,因为随机访问时间为O(n),而二进制搜索需要O(1)才能正常工作。

除非您选择不同的数据结构,否则您需要遍历列表,没有其他方法。

答案 3 :(得分:2)

使用find_if。如前所述,由于您无法访问列表中的随机元素,因此无法在binary_search上使用std::list

答案 4 :(得分:1)

您可以使用boost::flat_set在常规向量之上实现有序容器的语义。

答案 5 :(得分:0)

  

如何在列表中查找距离大于distance(19.0f)的第一个元素?如何申请清单二分搜寻? (迭代效率不高,列表很长)

正如其他一些回答者所说,二进制搜索不适用于std::list;但是如果您将list更改为vector,那么您要查找的算法将拼写为 std::partition_point

using Point = std::pair<float, float>;
float distance_between(Point, Point);

Point origin(0, 0);
std::vector<Point> points = { some stuff... };

// sort in ascending order by distance from origin point
std::sort(
    points.begin(), points.end(),
    [&](const auto& p1, const auto& p2) {
        return distance_between(origin, p1) < distance_between(origin, p2);
    }
);

现在这是您想知道的部分:

// find first element with distance bigger than 19.0f
auto it = std::partition_point(
    points.begin(), points.end(),
    [&](const auto& pt) {
        return distance_between(origin, pt) < 19.0f;
    }
);

返回的迭代器将是这样的:

if (it > points.begin()) {
    assert(distance_between(origin, *(it-1)) < 19.0f);
}
if (it < points.end()) {
    assert(distance_between(origin, *it) >= 19.0f);
}