专业的编程技术博客社区

网站首页 > 博客文章 正文

C++ STL sort 自定义规则排序小案例

baijin 2024-08-31 16:13:54 博客文章 3 ℃ 0 评论

相比C语言,C++学习起来比较烦,但是功能更强一些。

尤其是C++的STL标准模板库,可以说是很好很强大。

还是继续介绍不使用太多面向对象class, 只使用STL标准模板库的C++案例。


笔者在前面的文章中举了一个采用C++ STL标准模板库的例子,

实现了类似awk的功能,就是从文件中抓出来某一列。

那么能不能再多走一步,把文本文件的每一行按照某一列内容的字母大小进行排序,然后再写出来呢?

这就可以采用STL sort的自定义排序规则来实现。


用自定义的排序规则,对任何类型 T 的数组排序:

sort( 数组名 +n1 ,数组名 + n2, 排序规则结构名() )


排序规则结构的定义方式:

struct 结构名

{

bool operator() (const T & a1,const T & a2) const {

// 若 a1 应该 在 a2 前面,则返回 true 。

// 否则返回 false 。

}

};


我们首先构建一个结构体

struct Tag_line {

string line; // 存储从文件中抓出来的每一行

string tag; // 存储这一行中用于排序的那一列的字符串

} ;


然后定义排序规则的结构

struct column_sort_rule { // 按某一列字符串的字母顺序从小到大排序

bool operator() (const Tag_line & line1, const Tag_line & line2) const {

if( line1.tag < line2.tag )

return true;

return false;

}

};


从文件中抓出来的每一行里,再抓出来用于比较的那一列的内容,构成Tag_line类型的数据。

然后把Tag之后的每一行数据放在一个vector中存储,

vector<Tag_line> vec_tag_line_all;

然后对这个vector进行自定义规则sort, 就是

sort(vec_tag_line_all.begin(), vec_tag_line_all.end(), column_sort_rule());


注意:struct结构体的定义要放在main函数的外边


其他的细节请查看源代码,我在重点的地方都加了注释


程序源代码:


#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;

struct Tag_line {
 string line; // each line
 string tag; // the column to compare
} ;

struct column_sort_rule { // sort by the string of required column
 bool operator() (const Tag_line & line1, const Tag_line & line2) const {
 		if( line1.tag < line2.tag ) // the smaller string in front
 			return true;
 		return false;
 }
};

int main (int argc, char* argv[])
{
 //usage:
 //cmd input_file_name column_num

 if (argc < 3) {
 	cout << "Wrong input option number:" << argc -1 << endl;
 	cout << "Please inputi: file_name column_num" << endl;
 	return 0 ;
 }
  
 ifstream input_f(argv[1]) ; // input argv 1
 if ( !input_f ) { // check if input file can be opened
 	cout << "Error: the input file can not be opened" <<endl ;
 	return 0 ;
 }


 int column_num = atoi(argv[2]) ; // input argv 2
 if ( column_num <= 0 ) { // check if input column number is correct
	 	cout << "Error: wrong column number" << endl;
 		return 0;
 }

 vector<Tag_line> vec_tag_line_all; // all line after tag
 Tag_line tag_line_tmp; // each line after tag

 string i_line ; // each line from file
 //int line_num = 0 ;
 int line_length ; // total column number of each line
 vector<string> vec_line ; // store all element (sub string) of each line
 stringstream ss; // string stream
 string tmp_s; // each element and will be put into vec_line
  
 while ( getline(input_f, i_line) ) { // get each line
 		tag_line_tmp.line = i_line ; // put each line in struct .line
 		ss.clear(); // init string stream
 		ss << i_line ; // put each line to string stream
 		vec_line.clear(); // each line need init vec_line
 		while (ss >> tmp_s) { // each element (sub string) in each line
 			vec_line.push_back(tmp_s); // put into vec_line
 		}

 
 		line_length = vec_line.size() ; // get total colume number of each line
 		if ( column_num > 0 && column_num <= line_length) {
 		
 				tag_line_tmp.tag = vec_line[column_num - 1] ;
 		} else {
 				cout << "" << endl ; // if the line is empty or the required column > total column
 				tag_line_tmp.tag = "" ;
 		}

 		vec_tag_line_all.push_back(tag_line_tmp); // put tag line in vector
 }
  
 sort(vec_tag_line_all.begin(), vec_tag_line_all.end(), column_sort_rule());  // sort vector

 int line_num = vec_tag_line_all.size() ;
  
 for (int i = 0 ; i < line_num; ++i) {   // output sorted lines
 		cout << vec_tag_line_all[i].line << endl ;
 }


 input_f.close() ;

 return 0 ;
}

测试文件test.txt:

12 24 45 9 48 5

12 24 45 9 48 5
12 24 65 c 48 5
12 24 45 b 48 5
12 24 45 a 48 5

12 24 75 f 48 5
12 24 45 d 48 5
12 24 95 9 48 5
12 24 45 9 48 5

12 24 35 9 48 5
12 24 25 9 48 5

测试结果:

./a.out test.txt 3






12 24 25 9 48 5
12 24 35 9 48 5
12 24 45 9 48 5
12 24 45 9 48 5
12 24 45 b 48 5
12 24 45 a 48 5
12 24 45 d 48 5
12 24 45 9 48 5
12 24 65 c 48 5
12 24 75 f 48 5
12 24 95 9 48 5
./a.out test.txt 4






12 24 45 9 48 5
12 24 45 9 48 5
12 24 95 9 48 5
12 24 45 9 48 5
12 24 35 9 48 5
12 24 25 9 48 5
12 24 45 a 48 5
12 24 45 b 48 5
12 24 65 c 48 5
12 24 45 d 48 5
12 24 75 f 48 5

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表