在未排序向量中查找第 k 个最小元素(迭代)
Finding the Kth Smallest Element in an unsorted vector (Iteratively)
我正在尝试制作一个返回向量中第 k 个最小元素的代码。例如:假设您有一个包含元素 {0, 3, 2, 5} 的向量 rand用户输入 2 作为 K 的值。然后,该函数应从向量返回元素 2,因为它是向量中第 2 (k) 个最小元素。
到目前为止,这是我的代码:
int iterative_kth_element(vector<int>& vec, size_t k)
{
int index = 0;
int min = vec[0];
for(int i = k;i<vec.size();i--) {
for (int j = 1; j < vec.size();j++) {
if ( min > vec[j] ) {
min = vec[j];
index = i;
}
vec.erase(vec.begin() + index);
if (i == 1) {
return min;
}
}
}
}
它不断返回一些甚至不在向量中的大数字。
for(int i = k;i<vec.size();i--)
似乎不对,假设k
总是< vec.size()
,那么条件i<vec.size()
在这里完全没用。相反,您可能更愿意添加:
for(int i = k; i > 0; i--)
嵌套循环实际上应该检查所有元素,因此它应该从 0
开始(它跳过第一个元素):
for (int j = 0; j < vec.size(); j++) {
^
我相信
index = i;
本意是:
index = j;
并确保所有可能的执行路径都返回一些值,注意编译器给你的警告。在函数末尾再放一个return
语句:
return min;
但是你的主要问题是:
- 您应该在嵌套循环开始执行之前更新
min
- 嵌套循环的作用域不应包含
erase
调用
尝试:
int foo(std::vector<int>& vec, const size_t k)
{
int index = 0;
int min = -1;
for(size_t i = 0; i < k; ++i) {
if (vec.empty()) return min;
min = vec[0];
for (size_t j = 0; j < vec.size(); ++j) {
if (vec[j] < min) {
min = vec[j];
index = j;
}
}
vec.erase(vec.begin() + index);
}
return min;
}
int main() {
int a[] = {0, 3, 2, 5};
std::vector<int> v(a, a+4);
std::cout << foo(v, 2);
}
从这里开始: http://en.wikipedia.org/wiki/Selection_algorithm
int iterative_kth_element(vector<int>& vec, size_t k)
{
int minIndex, minValue;
for (int i = 0; i < k; i++)
{
minIndex = i;
minValue = vec[i];
for (int j = i+1; j < n; j++)
{
if (vec[j] < minValue)
{
minIndex = j;
minValue = vec[j];
}
}
int tmp = vec[i];
vec[i] = vec[minIndex];
vec[minIndex] = tmp;
}
return vec[k];
}
1/你有一个向量,但你几乎只把它作为一个数组使用
2/考虑使用迭代器。
3/您正在接收矢量作为参考,这意味着对它的修改(例如擦除元素)在方法范围之外是有效的,您真的要这样做吗?
这是我的解决方案的一些不完整的代码。它只需要在矢量上经过 1 次。这将以相对于 vec 的线性时间运行。希望它能解决问题。我以前的文字有点罗嗦。不过,我把它留在了这个来源下面。
int iterative_kth_element(vector<int>& vec, size_t k)
{
int mins[k];
//assume first k elements are min
for(int i=0; i<k; i++)
{
mins[i] = vec[i];
}
//TODO:
//sort mins array here
//bubble sort is okay if k is small, or pivot
for(int i=k; i < vec.size(); i++)
{
//since mins is sorted, mins[k-1] is the highest value
if(vec[i] < mins[k-1])
{
mins[k-1] = vec[i];
}
//TODO:
//sort mins array here
//you could do a slick bubble sort starting from
//the back of mins until you find the location
//for the new min item
}
return mins[k-1];
}
//以前的文本
如果您找到第 k 个最小的项目。您应该使用第一个 k 项初始化数组。或者将索引存储在 vec 中,在其中找到最小的项目。(以 0,1,2,3,...,k)
int index = 0;
int min = vec[0];
应该是
int* mins = new int[k];
for(int i=0; i < k; i++) {
mins[i] = vec[i];
}
我还建议对这个 k 个最小整数数组进行排序。如果您知道最大的项目在哪里,则只需根据最大的项目(以分钟为单位)检查 vec 中的每个元素。不过,您需要一个排序方法,每次您发现小于一分钟的内容时都会调用该方法。
在 vec 的一次迭代之后,您应该在该数组中拥有 k 个最小的项目。只需返回最大的项目。存储在阵列中的位置 0 或 k-1。
其他需要注意的事情:如果 k 大于 vec.size()/2,您应该查找 (vec.size() - k) 最大的项目。
这应该是 log(k*n) 时间,最大内存占用量为 1.5n(k 恰好是 vec.size()/2 的情况是最坏的情况)。
其中 n 是 vec 的大小,k 是函数中的参数。(如果实现该注释,K 的上限为 N/2)。
最坏的情况是按降序获取数字列表,其中 k 的大小是 n 的一半。
设置整数数组。
-
从数组中删除所有正元素,这些元素分配了在最大元素和最小元素之间。
-
计算数组负单元格的总和。
-
计算素元素的最小值
- 擦除while循环中迭代的元素
- 对于set上的循环-获取next元素迭代器
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- 高级选择排序 - 在一次迭代中搜索两个元素
- 访问要输出的矢量迭代器元素
- 为什么这个程序没有打印返回的迭代器的正确第二个元素?
- 位集元素迭代的抽象
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 调用 erase() 函数是否也会在擦除元素之前更改迭代器值?
- 为什么 min_element() 返回最小元素的索引,而不是迭代器?
- 如何将元素插入和迭代到这种映射.C++
- 如何通过查找迭代器结果分配给一组对的元素
- 在迭代期间添加到 std::unordered_set(或 unordered_map)中的元素是否会在迭代期间访问?
- 使用 Rcpp 加速替换迭代算法中的列表和向量元素是否合法?
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 如何在集合中迭代替代元素(或进行特定大小的飞跃)?
- 无法将 std::set 中的元素迭代器插入到 std::list
- 使用std :: remove_reference获取STL容器的元素迭代器
- C++ 从地图的第二个元素迭代
- 在未排序向量中查找第 k 个最小元素(迭代)