C++ 返回第k个最小元素的函数
我试图写一个函数,返回向量中第k个最小的元素。我必须迭代地执行此操作,并且无法对元素进行排序。下面是我到目前为止得到的结果,但我要么得到了一个分段错误,要么从向量中得到了一个不正确的数字。任何帮助都将不胜感激C++ 返回第k个最小元素的函数,c++,loops,vector,iteration,C++,Loops,Vector,Iteration,我试图写一个函数,返回向量中第k个最小的元素。我必须迭代地执行此操作,并且无法对元素进行排序。下面是我到目前为止得到的结果,但我要么得到了一个分段错误,要么从向量中得到了一个不正确的数字。任何帮助都将不胜感激 #include<vector> #include<iostream> using namespace std; int iterative_kth_element(vector<int> &vec, size_t k){ int cu
#include<vector>
#include<iostream>
using namespace std;
int iterative_kth_element(vector<int> &vec, size_t k){
int cur = 0;
int vecSmallestLocation = 0;
for(int i=0; i<k; i++){
if(vec.empty()){
return cur;
}
cur = vec[0];
for(int j=0; j<vec.size(); j++){
if(vec[j]<cur){
cur = vec[j];
vecSmallestLocation = j;
}
}
vec.erase(vec.begin()+(vecSmallestLocation));
}
cout << cur << endl;
return cur;
}
int main(){
vector<int> vec;
vec.push_back(6);
vec.push_back(21);
vec.push_back(98);
vec.push_back(14);
vec.push_back(5);
vec.push_back(7);
vec.push_back(9);
iterative_kth_element(vec, 3); // returns 6 but thats wrong
//iterative_kth_element(vec, 4); // seg fault
}
#包括
#包括
使用名称空间std;
int迭代元素(向量和向量,大小k){
int cur=0;
int vecsmalestlocation=0;
对于(int i=0;i它认为问题在于您没有在循环内初始化vecsmalestlocation
,它应该是
vecSmallestLocation = 0; // <-- this was missing
cur = vec[0];
for(int j=0; j<vec.size(); j++){
if(vec[j]<cur){
cur = vec[j];
vecSmallestLocation = j;
}
}
vec.erase(vec.begin()+(vecSmallestLocation));
为了避免此类错误。它认为问题在于您没有在循环内初始化vecsmalestlocation
,应该是
vecSmallestLocation = 0; // <-- this was missing
cur = vec[0];
for(int j=0; j<vec.size(); j++){
if(vec[j]<cur){
cur = vec[j];
vecSmallestLocation = j;
}
}
vec.erase(vec.begin()+(vecSmallestLocation));
避免此类错误。边缘情况可能导致分割错误。
由于变量vecsmalestlocation
不在循环的范围内,因此您将其带入循环。因此,请查看循环中的if语句:
if(vec[j]<cur){
cur = vec[j];
vecSmallestLocation = j;
}
if(vec[j]边缘情况可能导致分割错误。
由于变量vecsmalestlocation
不在循环的范围内,因此您将其带入循环。因此,请查看循环中的if语句:
if(vec[j]<cur){
cur = vec[j];
vecSmallestLocation = j;
}
if(vec[j]是的,托比指出的是正确的,你必须在内环外初始化VecssmallestLocation。就分段错误而言,这是因为你通过引用传递向量,你的函数正在修改向量并将其大小减小到3,并且在你的新向量中没有第四个最小的元素。所以不要通过引用来表示向量
下面是您的代码的修改版本。我试图尽可能少地修改它
#include<vector>
#include<iostream>
using namespace std;
void iterative_kth_element(vector<int> vec, size_t k)
{
int cur = 0;
int vecSmallestLocation = 0;
for(int i=0; i<k; i++)
{
if(vec.empty())
{
return ;
}
cur = vec[0];
vecSmallestLocation = 0;
for(int j=0; j<vec.size(); j++)
{
if(vec[j]<cur)
{
cur = vec[j];
vecSmallestLocation = j;
}
}
vec.erase(vec.begin()+(vecSmallestLocation));
}
cout << cur << endl;
}
int main(){
vector<int> vec;
vec.push_back(6);
vec.push_back(21);
vec.push_back(98);
vec.push_back(14);
vec.push_back(5);
vec.push_back(7);
vec.push_back(9);
iterative_kth_element(vec, 3);
iterative_kth_element(vec, 4);
}
#包括
#包括
使用名称空间std;
无效迭代元素(向量向量向量,大小k)
{
int cur=0;
int vecsmalestlocation=0;
对于(int i=0;i是的tobi指出的是正确的,您必须在内部循环外初始化VecssmallestLocation。就分段错误而言,这是因为您通过引用传递向量,并且您的函数正在修改向量并将其大小减小到3,并且在新向量中没有第四个最小元素。因此,不要通过引用传递向量
下面是您的代码的修改版本。我试图尽可能少地修改它
#include<vector>
#include<iostream>
using namespace std;
void iterative_kth_element(vector<int> vec, size_t k)
{
int cur = 0;
int vecSmallestLocation = 0;
for(int i=0; i<k; i++)
{
if(vec.empty())
{
return ;
}
cur = vec[0];
vecSmallestLocation = 0;
for(int j=0; j<vec.size(); j++)
{
if(vec[j]<cur)
{
cur = vec[j];
vecSmallestLocation = j;
}
}
vec.erase(vec.begin()+(vecSmallestLocation));
}
cout << cur << endl;
}
int main(){
vector<int> vec;
vec.push_back(6);
vec.push_back(21);
vec.push_back(98);
vec.push_back(14);
vec.push_back(5);
vec.push_back(7);
vec.push_back(9);
iterative_kth_element(vec, 3);
iterative_kth_element(vec, 4);
}
#包括
#包括
使用名称空间std;
无效迭代元素(向量向量向量,大小k)
{
int cur=0;
int vecsmalestlocation=0;
对于(int i=0;i我不知道如何做到这一点,而不必为每个连续的数字扫描整个向量(除非您密切关注左下一个最小的数字及其位置,因此每次读取时只需向右扫描所有内容)。您还必须处理两个数字相同的特殊情况。请记住,该算法是完全迭代的(即使是递归的),这意味着除非您进行排序,否则每个后续项都取决于前一项的知识。请记住将其分解为更简单的问题
你也真的不需要修改向量就可以做到这一点。根据你的描述,我不确定你为什么要在那里运行擦除
- 你如何找到第一个最小的数字?
- 扫描列表以查找最左边的最小数字
- 你如何找到下一个最小的数字?
- 扫描列表中与上一个相同但索引更大的下一个数字,或者如果不存在其他相同的数字,则给出下一个更大的数字(这对于避免返回相同的数字很重要)
- 您如何找到
i
th最小的数字?
- 重复算法,并保持计数
将例程分解为独立的、易于理解的部分
像这样的(我避免使用迭代器,因此我可以主要处理标记。在我自己的代码中,我将它们都泛化为只在迭代器上工作的模板,或者创建一个特殊的迭代器类型,这样我就可以按顺序完全迭代。还要注意,此代码不处理边缘情况,例如空向量或为k指定一个更大的值大于向量的大小):
#包括
#包括
使用名称空间std;
//获取最小值的索引
向量::大小\类型获取\最小\索引(常量向量和向量)
{
向量::大小\类型索引=0;
int最小值=vec.front();
对于(vector::size_type i=1;iprev_index&&vec[i]==vec[prev_index])
{
返回i;
}
//如果该值大于上一个值,且未设置下一个值或该值小于现有的下一个值
if(vec[i]>vec[prev_index]&&(next==prev_index | | vec[i]