std :: sort函数出现问题。经过2轮迭代,似乎对1个元素总是具有空值

我正在尝试编写一个排序程序,试图对我拥有的数据集进行排序。排序的关键是Grid_ID,它恰好是字母数字数据。我试图据此进行排序

它给我一个错误

  抛出'std :: out_of_range'实例后调用

terminate
  what():basic_string :: at:__n(0)> = this-> size()(   0)

在进行调试时,代码的读取部分似乎起作用。将文件内容读入DataContainer数据将填充正确的键和文本位置数据。 但是当涉及到std :: sort时,当调用程序“ less”时,const GridLabel&elem2总是在第二次迭代后变为零或空。

下面是一些数据集和部分源代码(我在这里不包括按排序顺序写内容,但应该可以运行)

感谢您的帮助!

这是部分数据集

Grid_Id,Speed,acc,ID
K31,173,8.37,1
K29,143,3.36,2
K29,107,4.56,3
K30,133,5.97,4
K30,153,2.38,5
J27,203,1.86,6
J27,1.59,7
I26,73,7.66,8
I27,134,2.86,9

这是代码

#include <algorithm>
#include <functional>
#include <fstream>
#include <string>

#include <deque>
#include <vector>

#include <iostream>
#include <sstream>

struct GridLabel
{
    std::string key_;
    std::istream::pos_type pos_;        // position in stream where this line starts

    GridLabel( const std::string& key,const std::istream::pos_type& pos) : key_( key),pos_( pos)
    {
    }

    const GridLabel& operator=( const GridLabel& other)
    {
        key_ = other.key_;
        pos_ = other.pos_;

        return *this;
    }
};

typedef std::vector<  GridLabel> DataContainer;

// Return whether first element is smaller than the second
bool less( const  GridLabel& elem1,const  GridLabel& elem2 )
{
   std::stringstream ss1,ss2;
   ss1 <<  elem1.key_.at(0);
   ss2 <<  elem2.key_.at(0);

   int value  = (ss1.str()).compare(ss2.str());

   if( value < 0 )
   {
       return true;
   }
   else if( value == 0)
   {
       // need to check if the rest are smaller
       std::string substr1 = elem1.key_.substr(1,std::string::npos);
       std::string substr2 = elem2.key_.substr(1,std::string::npos);

       return (std::atoi(substr1.c_str()) < std::atoi(substr2.c_str()));
   }
   else
   {
       return false;
   }
 }

int main(int argc,char* argv[])
{
   DataContainer data;

   // read data into the vector here
   std::ifstream input( "some_file.csv");

   // check if it is correct
   if ( !input.good())
   {
        std::cerr << "Input file can not be openned." << std::endl;
        return -1;
   }

   std::string text;
   std::string key;
   std::istream::pos_type pos;
   int count=0,save=0;

   // to skip the header
   std::getline( input,text);

   for( int line = 0; !input.eof(); ++line)
   {
      // store the position before reading the line
      pos = input.tellg();

      std::getline( input,text);

      // parse it
      save = text.find(",");

      key = text.substr(0,(save));

      data.push_back(  GridLabel( key,pos));
   }

   // sort the data in sorted order
   std::sort( data.begin(),data.end(),less);

   // create the new file
   ...............

   return 0;
}
randy09 回答:std :: sort函数出现问题。经过2轮迭代,似乎对1个元素总是具有空值

一个简化的less()进行比较

  1. GridLabel::key的前几个字符
  2. GridLabel::key的2 nd 个字符开始的整数。

这将不考虑GridLabel::key中存储的其他内容。 (这可能是OP想要的。)

示例:

#include <algorithm>
#include <iostream>
#include <string>

struct GridLabel {
  std::string key;
};

bool less(const GridLabel &elem1,const GridLabel &elem2)
{
  // compare first chars of keys
  const char c1 = elem1.key.at(0),c2 = elem2.key.at(0);
  if (c1 != c2) return c1 < c2;
  // compare integral beginning in 2nd char of keys
  const int i1 = atoi(elem1.key.c_str() + 1);
  const int i2 = atoi(elem2.key.c_str() + 1);
  return i1 < i2;
}

int main()
{
  GridLabel data[] = {
    { "K31,173,8.37,1" },{ "K29,143,3.36,2" },107,4.56,3" },{ "K30,133,5.97,4" },153,2.38,5" },{ "J27,203,1.86,6" },1.59,7" },{ "I26,73,7.66,8" },{ "I27,134,2.86,9" }
  };
  { std::cout << "Original data:\n";
    int i = 0;
    for (const GridLabel &entry : data) {
      std::cout << i++ << ": '" << entry.key << "'\n";
    }
  }
  std::cout << "Sorting...";
  std::sort(std::begin(data),std::end(data),less);
  std::cout << " Done.\n";
  { std::cout << "Sorted data:\n";
    int i = 0;
    for (const GridLabel &entry : data) {
      std::cout << i++ << ": '" << entry.key << "'\n";
    }
  }
}

输出:

Original data:
0: 'K31,1'
1: 'K29,2'
2: 'K29,3'
3: 'K30,4'
4: 'K30,5'
5: 'J27,6'
6: 'J27,7'
7: 'I26,8'
8: 'I27,9'
Sorting... Done.
Sorted data:
0: 'I26,8'
1: 'I27,9'
2: 'J27,6'
3: 'J27,7'
4: 'K29,2'
5: 'K29,3'
6: 'K30,4'
7: 'K30,5'
8: 'K31,1'

Live Demo on coliru

请注意(根据谓词less()的实现方式),有很多元素被认为是相等的:

  • I26,8I27,9
  • J27,6J27,7

这些元素在排序后将以任意顺序出现。

或者,可以使用std::stable_sort()来保留这些情况下的原始顺序。

本文链接:https://www.f2er.com/3140025.html

大家都在问