在std :: pair的排序列表中,按原点的距离按升序排序
pair<float,float> origin;
list<pair<float,float> > points;
float distance=19.0f;
如何找到距离大于距离(19.0f)的列表中的第一个元素? 如何申请列表二进制搜索? (迭代效率不高,列表很长)? 有更优雅的解决方案吗?
答案 0 :(得分:3)
列表不适合二进制搜索。这是因为您只能访问列表中的元素顺序(您只能从元素k
访问元素k-1
),因此如果您必须使用列表,除了线性搜索大于distance
的第一个元素之外别无选择。
如果您想进行二进制搜索,可以使用允许直接访问元素的vector
等容器(如myvector[i]
中所述)
答案 1 :(得分:2)
您不能在链接列表上进行二进制搜索。请考虑将其替换为vector
或multiset
。
答案 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);
}