sort()函數
sort()函數是定義在C++ STL 標准庫中的一個模板函數 ,它的作業是對容器或普通數組中指定范圍內的元素進行排序,排序規則默認以元素值的大小做升序排序,除此之外我們也可以選擇標准庫提供的其它排序規則(比如std::greater<T>
降序排序規則)。最重要的是我們可以使用函數的形式自定義排序規則,調用時只需要把我們自定義的排序函數作為參數傳入即可。
要使用sort(),我們需要包含頭文件<algorithm>。
#include <algorithm>
sort()本身的實現是基於快速排序,但並不是單純的快速排序。比如給一個數據量較大的數組排序,開始采用快速排序,分段遞歸,分段之后每一段的數據量達到一個較小值后它就不繼續往下遞歸,而是選擇插入排序,如果遞歸的太深,他會選擇推排序。具體實現源碼看着頭疼,就不管了,總之性能還是很好的。
需要注意的是,sort()函數要求參數容器的迭代器類型為RandomAccessIterator,即隨機訪問迭代器。這就意味着sort()函數目前只對數組 (array)、向量(vector)、雙隊列生效(deque)。
另外,若容器內含有多個相同值的元素,使用sort()排序時,可能會導致它們相對位置發生改變。
sort()函數有三個參數:
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
參數1:迭代器的起始位置,對於數組來說就是數組的首地址,一般寫上數組名就可以,因為數組名是一個指針常量。
參數2:迭代器的結束位置,即首地址加上數組的長度n(代表尾地址的下一地址)。
參數3:排序規則。默認可以不填,如果不填sort會默認按數組升序排序。也就是1,2,3,4。comp 可以是 C++ STL 標准庫提供的排序規則(比如 std::greater<T>),也可以是STL關聯式容器自定義排序規則,還可以直接定義一個具有 2 個參數並返回 bool 類型值的函數作為排序規則。
對於自定義函數的方法,當函數返回true的時候,關系表達式的左數將會排在數組靠前的位置。例如:
int A[100]; bool cmp1(int a,int b){ //降序排列 //return a>b; //默認的升序排列 return a<b; } sort(A,A+100,cmp1);
使用例:
能參加大運會,是每個大學生運動員的夢想。大運村男運動員和女運動員是分開入住的,每棟大樓都必須登記運動員的相關信息。登記好后,要按照一定的規則來排序生成編號以便管理。排序的規則是:
1)請按照國籍的字典序排序
2)如果國籍相同,年齡小的排在最前面
3)如果國籍,年齡都相同,請按照姓名的字典序排序。
人工來排,工作非常繁重,於是找到編程高手的你,來幫忙統計處理一下。
【輸入】
第一行一個整數n(0<n≤1000)n(0<n≤1000),表示大運村每棟樓入住的人數。
接下來nn行,每行三個數據,分別表示某個運動員的名字(不超過1010個字母,其間不含有空格)、年齡、國籍(三個大寫字母),一個空格隔開。
【輸出】
nn行,每行四個數據,排序后的編號(五位的字符串,編號不足五位前面補零)以及運動員的信息,均是一個空格隔開。
【輸入樣例】
5 Tom 21 USA Jack 21 USA Klac 22 FRA Ksd 21 FRA Takla 22 JPN
【輸出樣例】
00001 Ksd 21 FRA 00002 Klac 22 FRA 00003 Takla 22 JPN 00004 Jack 21 USA 00005 Tom 21 USA
【題解】
#include <iostream> #include <algorithm> #include <iomanip> using namespace std; //定義一個運動員類 class athleth { public: // 姓名 string name; // 年齡 int age; // 國籍 string country; }; /** * 定義排序規則,函數返回true的時候,關系表達式的左數將會排在數組靠前的位置 * 參數為兩個運動員對象 * @return */ bool cmp(athleth a,athleth b){ //兩個字符串比較大小時,是從左往右逐個比較ASCII碼 if(a.country<b.country){ return true; } else if(a.country==b.country&&a.age<b.age){ return true; } else if(a.country==b.country&&a.age==b.age&&a.name<b.name){ return true; }else{ return false; } } int main( ){ //獲取第一行輸入,共有y名選手 int n; cin>>n; //運動員數組 athleth ath[n]; //循環賦值 for (int i=0;i<n;i++){ cin>>ath[i].name>>ath[i].age>>ath[i].country; } //調用sort()函數簡化排序過程 sort(ath,ath+n,cmp); //輸出,注意序號中0的個數,使用右對齊補0的方式 for(int i = 0;i<n;i++){ //序號 cout<<setw(5)<<setfill('0')<<right<<i+1<<" "; //信息 cout<<ath[i].name<<" "<<ath[i].age<<" "<<ath[i].country<<endl; } return 0; }