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 }
本人还正在学习中,水平有限,如果哪里写的不当,还请指出,谢谢哈 !