C++ STL sort 自定義規則排序小案例

相比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 #include #include #include #include #include #include #include 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” < 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 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 512 24 45 9 48 512 24 65 c 48 512 24 45 b 48 512 24 45 a 48 512 24 75 f 48 512 24 45 d 48 512 24 95 9 48 512 24 45 9 48 512 24 35 9 48 512 24 25 9 48 5

測試結果:

。/a。out test。txt 312 24 25 9 48 512 24 35 9 48 512 24 45 9 48 512 24 45 9 48 512 24 45 b 48 512 24 45 a 48 512 24 45 d 48 512 24 45 9 48 512 24 65 c 48 512 24 75 f 48 512 24 95 9 48 5

。/a。out test。txt 412 24 45 9 48 512 24 45 9 48 512 24 95 9 48 512 24 45 9 48 512 24 35 9 48 512 24 25 9 48 512 24 45 a 48 512 24 45 b 48 512 24 65 c 48 512 24 45 d 48 512 24 75 f 48 5