前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >没想到!STL中sort有如此多亲戚邻居

没想到!STL中sort有如此多亲戚邻居

作者头像
用户9831583
发布2022-06-16 15:17:34
2010
发布2022-06-16 15:17:34
举报
文章被收录于专栏:码出名企路

sort可谓是排序鼻祖,今天就来挖挖她的亲戚邻居!

1.sort()

默认升序:

代码语言:javascript
复制
 //默认less
    std::vector<int> numbers {99, 77, 33, 66, 22, 88, 44, 88};
    std::sort(std::begin(numbers), std::end(numbers));
    std::copy(std::begin(numbers), std::end(numbers),
            ostream_iterator<int> {std::cout," "}) ;
    cout<<endl;

中间段序列排序:

代码语言:javascript
复制
//可以对中间某段元素排序
    std::sort(++std::begin(numbers),--std::end(numbers));
    std::copy(std::begin(numbers), std::end(numbers),
            ostream_iterator<int> {std::cout," "}) ;
     cout<<endl;

降序排列:

代码语言:javascript
复制
 //降序排列
    std::sort(std::begin(numbers), std::end(numbers), std::greater<int>());
    std::copy(std::begin(numbers), std::end(numbers),
            ostream_iterator<int> {std::cout," "}) ;
    cout<<endl;

labmda表达式自定义函数排序:

代码语言:javascript
复制
   //labmda表达式自定义比较函数
    std::deque<string> words { "one", "two", "nine", "nine", "one", "three", "four", "five", "six" };
    std::sort(std::begin(words), std::end(words),
            [](const string& s1, const string& s2) { return s1.back()> s2.back();});//最后一个字母做比较
    std::copy(std::begin(words), std::end(words),
            std::ostream_iterator<string> {std::cout," "}); // six four two one nine nine one three five
     cout<<endl;

注意:sort排序会打乱相等元素的顺序

2. stable_sort()

调整为:

代码语言:javascript
复制
//sort算法可能会改变相等元素的顺序
    //stable_sort()算法可以对一段元素进行排序并保证维持相等元素的原始顺序
    std::vector<int> numbers1{99, 77, 33, 66, 22, 88, 44, 88};
    std::stable_sort(std::begin(numbers1), std::end(numbers1));
    std::copy(std::begin(numbers1), std::end(numbers1),
            ostream_iterator<int> {std::cout," "}) ;
    cout<<endl;

3.partial_sort()

部分排序:

需要 3 个随机访问迭代器 first、second 和 last,[first,second) 会包含降序序列 [first,last) 中最小的 second-first 个元素。

代码语言:javascript
复制
 //部分排序
    size_t count {5};
    std::vector<int> numbers2{22, 7, 93, 45, 19, 56, 88, 12, 8, 7, 15, 10};
    std::partial_sort(std::begin(numbers2), std::begin(numbers2) + count, std::end(numbers2));
    std::copy(std::begin(numbers2), std::end(numbers2),
            ostream_iterator<int> {std::cout," "}) ;
    cout<<endl;

注意:不能保持未排序元素的原始顺序。元素的顺序是不确定的,这取决于我们的实现。

改为降序:

代码语言:javascript
复制
//前五个改为降序
    std::partial_sort(std::begin(numbers2), std::begin(numbers2) + count, std::end(numbers2) , std::greater<int>());
    std::copy(std::begin(numbers2), std::end(numbers2),
            ostream_iterator<int> {std::cout," "}) ;
    cout<<endl;

4.partial_sort_copy()

复制排序:

将排序元素复制到一个不同的容器中,它的前两个参数是指定部分排序应用范围的迭代器;第 3 个和第 4 个参数是标识结果存放位置的迭代器。

代码语言:javascript
复制
 //把排序后的部分元素重新保存在一个容器中,原来元素顺序不变
    std::vector<int> numbers3{22, 7, 93, 45, 19, 56, 88, 12, 8, 7, 15, 10};
    size_t count3{5};
    std::vector<int> result(count3);
    std::partial_sort_copy(std::begin(numbers), std::end(numbers), std::begin (result) , std::end (result));
    std::copy(std::begin(numbers3), std::end(numbers3), std::ostream_iterator<int>{std::cout," " });
    std::cout << std::endl;
    std::copy(std::begin(result), std::end(result),std::ostream_iterator <int> {std::cout, " "});
    std::cout << std::endl;

倒序:

代码语言:javascript
复制
std::partial_sort_copy(std::begin(numbers), std::end(numbers), std::begin(result), std::end(result),std::greater<int>());

5.nth_element() 在第 n 个元素之前的元素都小于第 n 个元素,而且它后面的每个元素都会比它大。

代码语言:javascript
复制
//找到小于某个数的数字序列
    std::vector<int> numbers4{22, 7, 93, 45, 19, 56, 88, 12, 8, 7, 15, 10};
    size_t count4 {5};
    std::nth_element(std::begin(numbers4), std::begin(numbers4) + count4, std::end(numbers4));
    std::copy(std::begin(numbers4), std::end(numbers4),std::ostream_iterator <int> {std::cout, " "});
    std::cout << std::endl;

第 n 个元素之前的元素都小于它,但不必是有序的。同样,第 n 个元素后的元素都大于它,但也不必是有序的。

自定义比比较函数:

代码语言:javascript
复制
std::nth_element(std::begin(numbers4), std::begin(numbers4) + count4, std::end(numbers4) , std::greater<int>());

6.is_sorted()

测试元素段是否已经排好序可以避免不必要的排序操作。

如果两个迭代器参数所指定范围内的元素是升序排列的,函数模板 is_sorted() 就会返回 true。

代码语言:javascript
复制
   //排序之前测试下是否已经排好序,省去了多余的排序
    std::vector<int> numbers5{22, 7, 93, 45, 19};
    std::vector<double> data{1.5, 2.5, 3.5, 4.5};
    std::cout << "numbers is "<<(std::is_sorted(std::begin(numbers5), std::end(numbers5)) ? "": "not ")
            << "in ascending sequence.\n";
    std::cout << "data is "<< (std::is_sorted(std::begin(data), std::end(data)) ?"":"not ")
             << "in ascending sequence." << std::endl;

自定义输出:

代码语言:javascript
复制
//自定义输出
    std:: cout << "data reversed is "<< (std::is_sorted(std::begin(data),
                    std::end(data), std::greater<double>()) ? "":"not ")<< "in descending sequence." << std::endl;

7.is_sorted_until()

来判断一个元素段是否有序,返回一个指向这段元素中升序序列上边界元素的迭代器。

代码语言:javascript
复制
//判断结果返回其中一个元素
    std::vector<string> pets{"cat", "chicken", "dog", "pig", "llama", "coati", "goat"};
    std::cout << "The pets in ascending sequence are:\n";
    std::copy(std::begin(pets), std::is_sorted_until(std::begin(pets), std::end (pets)) ,  std::ostream_iterator<string>{ std::cout," "});

"llama"是小于其前者的第一个元素,所以”pig”就是升序序列的第一个元素。

自定义:

代码语言:javascript
复制
  
std::vector<string> pets {"dog", "coati", "cat", "chicken", "pig", "llama", "goat"};
    std::cout << "The pets in descending sequence are:\n";
    std::copy(std::begin(pets),std::is_sorted_until(std::begin(pets), std::end (pets) , std::greater<string>()),std::ostream_iterator<string>{ std::cout," "});

8.合并两个有序序列merge()

合并操作会合并两个有相同顺序的序列中的元素,可以是两个升序序列,也可以是两个降序序列。结果会产生一个包含来自这两个输入序列的元素副本的序列,并且排序方式和原始序列相同.

代码语言:javascript
复制
//合并排序序列,并返回一个副本
    std::vector<int> these{2, 15, 4, 11, 6, 7};
    std::vector<int> those {5, 2, 3, 2, 14, 11, 6};
    std::stable_sort(std::begin(these), std::end(these),std::greater<int>());
    std::stable_sort(std::begin(those), std::end(those), std::greater<int>());
    std::vector<int> result6(these.size() + those.size() + 10);
    auto end_iter = std::merge(std::begin(these), std::end(these),std::begin(those), std::end(those),
            std::begin (result6), std::greater<int>());
    std::copy(std::begin (result6), end_iter, std::ostream_iterator<int>{std::cout, " "});

9.inplace_merge()

合并同一个序列中两个连续有序的元素序列。

data 容器有两个序列,并且都是升序序列。inplace_merge() 操作将它们合并为同一容器中的升序序列。

键盘输入,sort排序案例:

代码语言:javascript
复制
   .h
代码语言:javascript
复制
 #ifndef NAME_H
    #define NAME_H
    #include <string>                              
    class Name
    {
    private:
        std::string first {};
        std::string second {};
    public:
        Name(const std::string& name1, const std::string& name2) : first(name1), second(name2){}
        Name()=default;
        std::string get_first() const { return first; }
        std::string get_second() const { return second; }
        friend std::istream& operator>>(std::istream& in, Name& name);
        friend std::ostream& operator<<(std::ostream& out, const Name& name);
    };
    
    inline std::istream& operator>>(std::istream& in, Name& name)
    {
        return in >> name.first >> name.second;
    }
  
    inline std::ostream& operator<<(std::ostream& out, const Name& name)
    {
        return out << name.first << " " << name.second;
    }
    #endif
代码语言:javascript
复制
.cpp
代码语言:javascript
复制
 #include <iostream>                            
    #include <string>                              
    #include <vector>                              
    #include <iterator>                            
    #include <algorithm>                            
    #include "s.h"
    int main()
{
        std::vector<Name> names;
        std::cout << "Enter names as first name followed by second name. Enter Ctrl+Z to end:";
        std::copy(std::istream_iterator<Name>(std::cin), std::istream_iterator<Name>(),
                    std::back_insert_iterator<std::vector<Name>>(names));
        std::cout << names.size() << " names read. Sorting in ascending sequence...\n";

        std::sort(std::begin(names), std::end(names),
                     [](const Name& name1, const Name& name2) {return name1.get_second() < name2.get_second(); });
        std::cout << "\nThe names in ascending sequence are:\n";
        
        std::copy(std::begin(names), std::end(names), std::ostream_iterator<Name>(std::cout, "\n"));
    }

结果显示:


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档