Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回第k个最小元素的函数_C++_Loops_Vector_Iteration - Fatal编程技术网

C++ 返回第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

我试图写一个函数,返回向量中第k个最小的元素。我必须迭代地执行此操作,并且无法对元素进行排序。下面是我到目前为止得到的结果,但我要么得到了一个分段错误,要么从向量中得到了一个不正确的数字。任何帮助都将不胜感激

#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]