中sort()函數的用法


   先說一下,本篇文章我沒有講sort()實現排序的原理,我寫在另一篇文章中了,如果想了解的話,可以看一下,附上鏈接:https://www.cnblogs.com/buanxu/p/12772700.html

   sort(v.begin(),v.end(),cmp),它是用來對一組序列進行排序的;有三個參數,前兩個參數是待排序區間;第三個參數可有可無(第三個參數代表比較規則),

沒有第三個參數的時候,sort()默認按升序排列,有第三個參數的時候,可以通過這個參數實現各種各樣的排序,包括降序。sort()函數功能強大就是強大在

第三個參數,后面會講到。

   sort()函數除了可以對int型、char型、double型、字符串排序外,還可以實現對結構體、鏈表、pair、vector、等類型進行排序,但需要自己寫比較函數,后面

也會講到。而且sort()既可以對數組排序,也可以對vector容器排序。下面就先說一下sort()只有兩個參數時的用法,看代碼吧,寫的比較詳細,列舉了多種情況

 1 #include<iostream>
 2 #include<vector>
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 int main()
 7 {
 8     int a[10]={6,5,4,8,3,9,7,10,1,2};
 9     char b[8]={'h','z','l','n','m','r','d','g'};
10     vector<double> v1;
11     vector<string> v2;
12     v1.push_back(3.6);
13     v1.push_back(0.8);
14     v1.push_back(-0.5);
15     v1.push_back(-2.4);
16     v1.push_back(1.2);
17     v2.push_back("abcde");
18     v2.push_back("fdbcde");
19     v2.push_back("apcde");
20     v2.push_back("fdbcdc");
21     v2.push_back("fdbc");
22 
23     cout<<"對a排序前:";
24     for(int i=0;i<10;i++)
25         cout<<a[i]<<" ";
26     cout<<"\n對a排序后:";
27     sort(a+1,a+9);    //可以指定任意合法的排序區間,不能越界
28     for(int i=0;i<10;i++)
29         cout<<a[i]<<" ";
30 
31     cout<<"\n\n對b排序前:";
32     for(int i=0;i<8;i++)
33         cout<<b[i]<<" ";
34     cout<<"\n對b排序后:";
35     sort(b,b+8);     //對整個b排序
36     for(int i=0;i<8;i++)
37         cout<<b[i]<<" ";
38 
39     cout<<"\n\n對v1排序前:";
40     for(int i=0;i<v1.size();i++)
41         cout<<v1[i]<<" ";
42     cout<<"\n對v1排序后:";
43     sort(v1.begin(),v1.end());
44     for(int i=0;i<v1.size();i++)
45         cout<<v1[i]<<" ";
46 
47     cout<<"\n\n對v2排序前:";
48     for(int i=0;i<v2.size();i++)
49         cout<<v2[i]<<" ";
50     cout<<"\n對v2排序后:";
51     sort(v2.begin(),v2.end());
52     for(int i=0;i<v2.size();i++)
53         cout<<v2[i]<<" ";
54     cout<<"\n";
55     return 0;
56 }

結果如下:

 

上面列舉了幾種常見數據類型排序后的結果,但是它們都是按升序排列的,要想按降序排列,有3種方法。為了給大家講的更詳細一點,在第一個方法中我

用了好幾種數據類型;后面兩種方法就只用了一種數據類型,以減少篇幅。

 

1. sort()函數只有兩個參數時默認升序排列,在排完序后,再用reverse()函數把整個序列給翻轉一下,這樣序列就變成了降序;把上面的代碼改一下就好了

 1 #include<iostream>
 2 #include<vector>
 3 #include<string>
 4 #include<algorithm>
 5 using namespace std;
 6 int main()
 7 {
 8     int a[10]={6,5,4,8,3,9,7,10,1,2};
 9     char b[8]={'h','z','l','n','m','r','d','g'};
10     vector<double> v1;
11     vector<string> v2;
12     v1.push_back(3.6);
13     v1.push_back(0.8);
14     v1.push_back(-0.5);
15     v1.push_back(-2.4);
16     v1.push_back(1.2);
17     v2.push_back("abcde");
18     v2.push_back("fdbcde");
19     v2.push_back("apcde");
20     v2.push_back("fdbcdc");
21     v2.push_back("fdbc");
22 
23     cout<<"對a排序前:";
24     for(int i=0;i<10;i++)
25         cout<<a[i]<<" ";
26     cout<<"\n對a默認排序后:";
27     sort(a+1,a+9);    //可以指定任意合法的排序區間,不能越界
28     for(int i=0;i<10;i++)
29         cout<<a[i]<<" ";
30     cout<<"\n對a降序排序后:";
31     reverse(a+1,a+9);
32     for(int i=0;i<10;i++)
33         cout<<a[i]<<" ";
34 
35     cout<<"\n\n對b排序前:";
36     for(int i=0;i<8;i++)
37         cout<<b[i]<<" ";
38     cout<<"\n對b默認排序后:";
39     sort(b,b+8);     //對整個b排序
40     for(int i=0;i<8;i++)
41         cout<<b[i]<<" ";
42     cout<<"\n對b降序排序后:";
43     reverse(b,b+8);
44     for(int i=0;i<8;i++)
45         cout<<b[i]<<" ";
46 
47     cout<<"\n\n對v1排序前:";
48     for(int i=0;i<v1.size();i++)
49         cout<<v1[i]<<" ";
50     cout<<"\n對v1排序后:";
51     sort(v1.begin(),v1.end());
52     for(int i=0;i<v1.size();i++)
53         cout<<v1[i]<<" ";
54     cout<<"\n對v1默認排序后:";
55     reverse(v1.begin(),v1.end());
56     for(int i=0;i<v1.size();i++)
57         cout<<v1[i]<<" ";
58 
59     cout<<"\n\n對v2排序前:";
60     for(int i=0;i<v2.size();i++)
61         cout<<v2[i]<<" ";
62     cout<<"\n對v2排序后:";
63     sort(v2.begin(),v2.end());
64     for(int i=0;i<v2.size();i++)
65         cout<<v2[i]<<" ";
66     cout<<"\n對v2默認排序后:";
67     reverse(v2.begin(),v2.end());
68     for(int i=0;i<v2.size();i++)
69         cout<<v2[i]<<" ";
70     cout<<"\n";
71     return 0;
72 }

結果如下:

可以看到,在用reverse()翻轉后就變成了降序,這里提醒一下,為了節省篇幅,讓大家看起來更流暢,下面兩個方法都將只使用一種數據類型了,以減少代碼長度

 

2. 除了用reverse()翻轉外,還可以借助c++標准庫來實現降序(或升序)。此時要包含頭文件<functional>,<functional>頭文件提供了一些基於模板的比較函數對象,

    這里在排序的時候只用到了  greater<type>() 和 less<type>() 兩個;讓 greater<type>() 或 less<type>() 做sort()函數的第三個參數來實現升序或降序排列;其中

    greater<type>() 用於降序排列,less<type>() 用於升序排列,具體用法看代碼

 1 #include<iostream>
 2 #include<functional>
 3 #include<algorithm>
 4 using namespace std;
 5 int main()
 6 {
 7     int a[10]={6,5,4,8,3,9,7,10,1,2};
 8 
 9     cout<<"對a排序前:";
10     for(int i=0;i<10;i++)
11         cout<<a[i]<<" ";
12 
13     cout<<"\n對a降序排列后:";
14     sort(a,a+10,greater<int>());
15     for(int i=0;i<10;i++)
16         cout<<a[i]<<" ";
17 
18     cout<<"\n對a升序排列后:";
19     sort(a,a+10,less<int>());
20     for(int i=0;i<10;i++)
21         cout<<a[i]<<" ";
22     cout<<"\n";
23     return 0;
24 }

結果如下圖:

3. 第三個方法是自己寫一個比較函數來實現升序或降序排列,並讓這個比較函數做sort()函數的第三個參數;其實比較函數不僅能實現升序降序排列,還能實現其他的功能。

    這就是sort()函數功能強大的地方,它可以擴展,而擴展的關鍵就是第三個參數,所以我把這種方法放在最后講。

    先說一下比較函數吧,當你想實現特定比較方式的時候,就要自己定義一個返回bool值的比較函數了;這時sort()函數的第三個參數就是一個函數,如果它返回假值就交換

    操作對象的位置,返回真值的話操作對象位置不變。下面就用比較函數來實現升序降序的排列,看代碼

 

 1 #include<iostream>
 2 #include<functional>
 3 #include<algorithm>
 4 using namespace std;
 5 bool cmp1(int a,int b)  //按降序排列
 6 {
 7     return a>b;
 8 }
 9 
10 bool cmp2(int a,int b)  //按升序排列
11 {
12     return a<b;
13 }
14 int main()
15 {
16     int a[10]={6,5,4,8,3,9,7,10,1,2};
17 
18     cout<<"對a排序前:";
19     for(int i=0;i<10;i++)
20         cout<<a[i]<<" ";
21 
22     cout<<"\n對a降序排列后:";
23     sort(a,a+10,cmp1);   //這里不需要對比較函數cmp1傳入參數
24     for(int i=0;i<10;i++)
25         cout<<a[i]<<" ";
26 
27     cout<<"\n對a升序排列后:";
28     sort(a,a+10,cmp2);   ////不需要對比較函數cmp2傳入參數
29     for(int i=0;i<10;i++)
30         cout<<a[i]<<" ";
31     cout<<"\n";
32     return 0;
33 }

結果看下圖:

這里對比較函數的原理介紹一下: bool cmp(int a, int b);在定義這個比較函數的時候要明確比較對象的數據類型,這里是int型,也可以是其他的任意類型,比如結構體、vector、鏈表等。

但是在使用的時候(即做sort()函數的第三個參數時)不用對cmp傳入參數,這是需要注意的地方。下面就是比較原理了

bool cmp(int a,int b)  
{
 return a>b;
}

sort(a,a+10,cmp);

sort() 操作的對象數組或vector中兩個挨着的順序元素分別賦值到a和b上,通過一系列操作(這個操作就是你寫的比較函數要實現的功能)后,返回bool值。

 

上面的sort()函數都是對簡單的數據類型進行排序,那之前也說過,sort()還可以對結構體、鏈表、vector等排序,不過還是要你自己去寫比較函數的。這里就用結構體舉例了,

下面通過一道題來體現比較函數的強大功能,這是之前我刷過的PTA的一道題。題目如下

 

其實這道題就要用到比較函數,用比較函數來實現sort()對結構體的排序,而且這里的比較函數要比之前寫的比較函數cmp1和cmp2復雜點,並且比較對象都是結構體。

下面只貼出了封裝的結構體和比較函數的代碼

 

 1 struct student{
 2     int id,dscore,cscore;
 3     int sum;//總分
 4 };
 5 bool cmp(student a,student b)
 6 {    //按降序排列
 7     if(a.sum!=b.sum)
 8         return a.sum>b.sum; //優先按總分的高低排序
 9     else if(a.dscore!=b.dscore)
10         return a.dscore>b.dscore; //總分相同則優先按德分排序
11     else
12         return a.id<b.id; //總分和德分都相同則按學號排序
13 }

本題我在  “PTA刷題” 隨筆里面詳細講到了,里面有完整代碼,想看的可以去看一下,附上鏈接:

本人還正在學習中,水平有限,如果哪里寫的不當,還請指出,謝謝哈 !


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM