如何将 lower_bound 应用于一系列未排序的向量元素?
Posted
技术标签:
【中文标题】如何将 lower_bound 应用于一系列未排序的向量元素?【英文标题】:How do i apply lower_bound to a range of unsorted vector elements? 【发布时间】:2020-10-01 06:54:49 【问题描述】:我有一个整数向量scores = 10, 23, 29, 77, 8, 43, 56, 3
连同一个号码predict = 42
和start index = 2
我正在搜索两个数字,(大于和小于)接近predict = 42
,在start index = 2
和end index = 7
的范围内
scores = 10, 23, 29, 77, 8, 43, 56, 3 (仅在 i=2 到 i=7 范围内搜索)
所以,
29
比 predict=42 少一点而且,
43
比预测的 42 多一点
我如何获得这些数字?
示例代码:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
vector<int> scores = 10, 23, 29, 77, 8, 43, 56, 3; //Unsorted
int predict = 42;
int startFromIndex = 2;
int littleLessThanPredict; // = 29
int littleMoreThanPredict; // = 43
//lower_bound
//upper_bound
return 0;
鉴于这种情况,
-
如何在未排序的范围内使用
std::lower_bound
和std::upper_bound
函数?
如何临时对向量的一部分进行排序并应用我的自定义函数?
有没有办法结合std::min_element
和std::lower_bound
函数来获得想要的结果?
【问题讨论】:
也许任务是让你自己想出一个算法?任务的要求和限制是什么?你从哪里得到的任务?你有没有和你的教授/老师/助教谈过这个(如果是学校作业)? 不是学校作业,它是一个控制台/文本游戏,而且,我正在尝试在其中一个步骤中实现此功能。我无法弄清楚 lambda 函数或异地排序算法的语法 我不明白你为什么需要lower/upper_bound
。你不能只 for 循环从start index
开始并以end index
结束,如果你发现一个低于predict
的数字,你把它保存在littleLessThanPredict
,如果它更大,你把它保存在littleMoreThanPredict
。然后继续,如果你找到一个大于littleLessThanPredict
但小于predict
的数字,你更新littleLessThanPredict
,如果你找到一个小于littleMoreThanPredict
但大于predict
的数字,你更新littleMoreThanPredict
。跨度>
如果对分数进行了排序,lower_bound(scores.begin(), scores.end(), 42)
将返回一个指向 43 而不是 29 的迭代器
【参考方案1】:
如何在未排序的范围内使用 std::lower_bound 和 std::upper_bound 函数?
不,他们希望根据 value 对范围进行分区(所有小于 value 的条目必须在所有大于的条目之前)。 https://en.cppreference.com/w/cpp/algorithm/lower_bound
如何临时对向量的一部分进行排序并应用我的自定义函数?
如果您正在处理数字,也许最简单的方法是创建向量的副本并对其进行排序。这是 O(NlogN) 复杂度。
您也可以通过自己实现 lower_bound 来获得良好的性能(这将是 O(N))。
经验法则:如果您的数组通常很短(
有没有办法结合 std::min_element 和 std::lower_bound 函数来获得想要的结果?
不是真的。
【讨论】:
如果它是一个非常大的数组?我在这里寻找性能 @PersistentCache 在这种情况下,您需要自己实现 lower_bound 。这是一个 for 循环,您可以在其中查找大于目标值的最小元素。 @PersistentCache “非常大”是相对的。你谈论成千上万的元素吗?几万?数十万?对于数以千计的元素,现代计算机的速度足够快,可以处理甚至相当无效的算法。更不用说对于主机游戏,大部分时间都是程序处于空闲状态并等待用户输入。 @PersistentCache 分析您的代码也是一个好习惯。与从中获得最佳性能相比,从长远来看,可能还有其他热点会产生更大的影响。 理想情况下,15,000 个元素的向量大小应该可以。【参考方案2】:为什么需要对数组进行排序?这将给出 O(N.ln(N)) 算法复杂度。
您可以在 O(N) 中结合未排序数组中的上限和下限研究来执行您的算法:
#include <algorithm>
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
pair<int, int> nearestNumbers(const vector<int> &scores, int predict, int start)
int nearestLower = INT_MIN;
int nearestUpper = INT_MAX;
for (size_t i = start; i < scores.size(); i++)
int value = scores[i];
if (value <= predict && value > nearestLower)
nearestLower = value;
else if (value >= predict && value < nearestUpper)
nearestUpper = value;
return pair<int, int>(nearestLower, nearestUpper);
int main()
vector<int> scores = 10, 23, 29, 77, 8, 43, 56, 3;
int predict = 42;
int start = 2;
pair<int, int> results = nearestNumbers(scores, predict, start);
cout << results.first << " " << results.second;
return 0;
【讨论】:
【参考方案3】:如果分数数组很小(对于某些未指定的“小”值),则无需对分数进行排序。
如果我没有正确阅读问题,您正在寻找小于predict
的最大值和大于predict
的最小值。那就这样做吧:
int lower = INT_MAX;
int upper = INT_MIN;
for (int i = start; i <= end; ++i)
if (scores[i] < predict)
lower = std::max(lower, scores[i]);
else
upper = std::min(upper, scores[i]);
请注意,如果其中一个分数等于predict
,则此代码将该值放入upper
。如果这不是您想要的,则需要相应地调整代码。
【讨论】:
以上是关于如何将 lower_bound 应用于一系列未排序的向量元素?的主要内容,如果未能解决你的问题,请参考以下文章