"Best"从容器中选择k个最小元素的(惯用)方法C++
"Best" (idiomatic) way to select the k smallest elements from a container in C++
我发现自己经常遇到这个问题:给定一个序列,找到k最小的元素。这个问题并不难,但我想要的是一种既安全(很少出错)又能很好地传达意图的"惯用"方法。所以最后要做的是对序列进行排序,然后取第一个k元素:
std::sort(container.begin(),container.end());
std::vector<T> k_smallest(container.begin(),container.begin() + k);
在我看来,这既安全又容易理解,但这里的复杂性是nlogn+k,而不仅仅是n。你们是如何做到这一点的,有没有一种idomatic的方法(使用一些模糊的函数)可以在不需要重新实现轮子的情况下提供最佳的复杂性
std::nth_element()-平均线性复杂度。
nth_element
是一种部分排序算法,它在[第一,最后)使得:
- 由第n个指向的元素被更改为如果对[第一个,最后一个)进行排序,则该位置将出现的任何元素
- 该新的第n个元素之前的所有元素都小于或等于新的第N个元素之后的元素
您可能想看看partial_sort()
它理解起来很简单,不需要额外的工作,并且如果只关心第k个元素,那么它会比sort()
更好[或者至少不会更差]。
为了获得最佳性能,您可能想要使用选择算法,但这需要更多的工作。
第一个算法:
步骤:
- 使用"选择"算法查找第k_th个元素
- 选择它作为枢轴并执行分区(来自快速排序算法),从而使枢轴剩下最小的k个元素
复杂性:O(n)最坏情况
第二算法:
步骤:
- 使用make_heap从数组元素中创建堆
- 执行k次以下操作:
- 读取第一个元素
- 使用pop_heap弹出
您可以使用priority队列的方法(c'tor、top、pop)来实现相同的结果,而不需要知道后面的算法。
复杂性:O(n+k*log(n))最坏情况
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 枚举环境变量的惯用C++14/C++17方法
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 从任意容器中廉价删除元素的惯用方法?
- 按元素添加两个范围的惯用和有效方法
- "Best"从容器中选择k个最小元素的(惯用)方法C++
- 用于从 std::map 的最后 n 个元素创建 std::vector 的惯用C++