问题描述
我正在尝试编写一个排序程序,试图对我拥有的数据集进行排序.排序的关键是Grid_ID,它恰好是字母数字数据.我试图据此进行排序
I am trying to write a sort program trying to sort a data set I have. The key to the sorting is Grid_ID and it happened to be an alpha-numeric data. I have tried to sort accordingly
它给我一个错误
在进行调试时,代码的读取部分似乎起作用.将文件内容读取到DataContainer数据中将填充正确的键和文本位置数据.但是当涉及到std :: sort时,当程序"less"被调用时,const GridLabel&第二次迭代后,elem2总是变为零或为空
On doing debugging, the reading part of the code seems to function. The reading of file content into DataContainer data get filled with the right data of key and text position.But when it come to std::sort, when the program "less" is invoked, const GridLabel& elem2 always turn up to be zero or null after 2nd iteration
下面是一些数据集和部分源代码(我在这里不包括按排序顺序写内容,但应该可以运行)
Below is some data set and partial source code (I do not include the write the content in sorted order here but should be runnable)
感谢您的帮助!
这是部分数据集
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,143,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;
}
推荐答案
一个简化的 less()
进行比较
-
GridLabel :: key
的前几个字符 - 从
GridLabel :: key
的2 个字符开始的整数.
- the first characters of
GridLabel::key
- the integral number starting from 2 character of
GridLabel::key
.
这不会考虑 GridLabel :: key
中还存储了什么.(这可能是OP想要的.)
This will not consider what else is stored in GridLabel::key
. (This might be intended by 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" },
{ "K29,107,4.56,3" },
{ "K30,133,5.97,4" },
{ "K30,153,2.38,5" },
{ "J27,203,1.86,6" },
{ "J27,143,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,173,8.37,1'
1: 'K29,143,3.36,2'
2: 'K29,107,4.56,3'
3: 'K30,133,5.97,4'
4: 'K30,153,2.38,5'
5: 'J27,203,1.86,6'
6: 'J27,143,1.59,7'
7: 'I26,73,7.66,8'
8: 'I27,134,2.86,9'
Sorting... Done.
Sorted data:
0: 'I26,73,7.66,8'
1: 'I27,134,2.86,9'
2: 'J27,203,1.86,6'
3: 'J27,143,1.59,7'
4: 'K29,143,3.36,2'
5: 'K29,107,4.56,3'
6: 'K30,133,5.97,4'
7: 'K30,153,2.38,5'
8: 'K31,173,8.37,1'
请注意(根据谓词 less()
的实现方式),有很多元素被认为是相等的:
Please, note that (according to how predicate less()
is implemented) there are a lot elements which are considered as equal:
-
I26,73,7.66,8
与I27,134,2.86,9
-
J27,203,1.86,6
和J27,143,1.59,7
- 等
这些元素在排序后将以任意顺序出现.
These elements will appear in abitrary order after sorting.
或者, std :: stable_sort()
在这种情况下,可以使用a>保留原始顺序.
Alternatively, std::stable_sort()
could be used which will preserve the original order in these cases.
这篇关于std :: sort函数出现问题.经过2轮迭代,似乎对1个元素总是具有null值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!