zoukankan      html  css  js  c++  java
  • <algorithm>中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<<"
    对a排序后:";
    27     sort(a+1,a+9);    //可以指定任意合法的排序区间,不能越界
    28     for(int i=0;i<10;i++)
    29         cout<<a[i]<<" ";
    30 
    31     cout<<"
    
    对b排序前:";
    32     for(int i=0;i<8;i++)
    33         cout<<b[i]<<" ";
    34     cout<<"
    对b排序后:";
    35     sort(b,b+8);     //对整个b排序
    36     for(int i=0;i<8;i++)
    37         cout<<b[i]<<" ";
    38 
    39     cout<<"
    
    对v1排序前:";
    40     for(int i=0;i<v1.size();i++)
    41         cout<<v1[i]<<" ";
    42     cout<<"
    对v1排序后:";
    43     sort(v1.begin(),v1.end());
    44     for(int i=0;i<v1.size();i++)
    45         cout<<v1[i]<<" ";
    46 
    47     cout<<"
    
    对v2排序前:";
    48     for(int i=0;i<v2.size();i++)
    49         cout<<v2[i]<<" ";
    50     cout<<"
    对v2排序后:";
    51     sort(v2.begin(),v2.end());
    52     for(int i=0;i<v2.size();i++)
    53         cout<<v2[i]<<" ";
    54     cout<<"
    ";
    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<<"
    对a默认排序后:";
    27     sort(a+1,a+9);    //可以指定任意合法的排序区间,不能越界
    28     for(int i=0;i<10;i++)
    29         cout<<a[i]<<" ";
    30     cout<<"
    对a降序排序后:";
    31     reverse(a+1,a+9);
    32     for(int i=0;i<10;i++)
    33         cout<<a[i]<<" ";
    34 
    35     cout<<"
    
    对b排序前:";
    36     for(int i=0;i<8;i++)
    37         cout<<b[i]<<" ";
    38     cout<<"
    对b默认排序后:";
    39     sort(b,b+8);     //对整个b排序
    40     for(int i=0;i<8;i++)
    41         cout<<b[i]<<" ";
    42     cout<<"
    对b降序排序后:";
    43     reverse(b,b+8);
    44     for(int i=0;i<8;i++)
    45         cout<<b[i]<<" ";
    46 
    47     cout<<"
    
    对v1排序前:";
    48     for(int i=0;i<v1.size();i++)
    49         cout<<v1[i]<<" ";
    50     cout<<"
    对v1排序后:";
    51     sort(v1.begin(),v1.end());
    52     for(int i=0;i<v1.size();i++)
    53         cout<<v1[i]<<" ";
    54     cout<<"
    对v1默认排序后:";
    55     reverse(v1.begin(),v1.end());
    56     for(int i=0;i<v1.size();i++)
    57         cout<<v1[i]<<" ";
    58 
    59     cout<<"
    
    对v2排序前:";
    60     for(int i=0;i<v2.size();i++)
    61         cout<<v2[i]<<" ";
    62     cout<<"
    对v2排序后:";
    63     sort(v2.begin(),v2.end());
    64     for(int i=0;i<v2.size();i++)
    65         cout<<v2[i]<<" ";
    66     cout<<"
    对v2默认排序后:";
    67     reverse(v2.begin(),v2.end());
    68     for(int i=0;i<v2.size();i++)
    69         cout<<v2[i]<<" ";
    70     cout<<"
    ";
    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<<"
    对a降序排列后:";
    14     sort(a,a+10,greater<int>());
    15     for(int i=0;i<10;i++)
    16         cout<<a[i]<<" ";
    17 
    18     cout<<"
    对a升序排列后:";
    19     sort(a,a+10,less<int>());
    20     for(int i=0;i<10;i++)
    21         cout<<a[i]<<" ";
    22     cout<<"
    ";
    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<<"
    对a降序排列后:";
    23     sort(a,a+10,cmp1);   //这里不需要对比较函数cmp1传入参数
    24     for(int i=0;i<10;i++)
    25         cout<<a[i]<<" ";
    26 
    27     cout<<"
    对a升序排列后:";
    28     sort(a,a+10,cmp2);   ////不需要对比较函数cmp2传入参数
    29     for(int i=0;i<10;i++)
    30         cout<<a[i]<<" ";
    31     cout<<"
    ";
    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刷题” 随笔里面详细讲到了,里面有完整代码,想看的可以去看一下,附上链接:

    本人还正在学习中,水平有限,如果哪里写的不当,还请指出,谢谢哈 !

  • 相关阅读:
    Mysql之存储过程与存储函数
    mysql-bin日志自动清理及手动删除
    mysql下面的binlog
    mysql下的数据备份与恢复
    查询mysql数据库中各个表所占空间大小以及索引大小
    mysql执行sql语句报错this is incompatible with sql_mode=only_full_group_by
    docker WARNING: IPv4 forwarding is disabled. 解决方法
    Linux平台修改环境变量的方式
    PuTsangTo
    (一) 从Angular1到Angular2的杂谈
  • 原文地址:https://www.cnblogs.com/buanxu/p/12771502.html
Copyright © 2011-2022 走看看