zoukankan      html  css  js  c++  java
  • c++ 集合排序

    std::sort vector string

    我们先看一下 std::sort 的定义。头文件

    template< class RandomIt >
    void sort( RandomIt first, RandomIt last ); (1)
    
    template< class RandomIt, class Compare >
    void sort( RandomIt first, RandomIt last, Compare comp ); (2)
    

    Sorts the elements in the range [first, last) in non-descending order. The order of equal elements is not guaranteed to be preserved. 【即不稳定排序】
    (1)式:Elements are compared using operator<.【默认使用operator<运算符比较】
    (2)式:Elements are compared using the given binary comparison function comp.【使用comp比较元素大小】

    关于 comp 参数:

    The signature of the comparison function should be equivalent to the following: 
     bool cmp(const Type1 &a, const Type2 &b);
    
    若第一参数小于(即先序于)第二参数则返回 ​true。cmp函数为bool类型,那么如果返回true,相当于不交换位置
    

    复杂度:
    平均 O(N·log(N)) 次比较,其中 N = std::distance(first, last)

    例子:

    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    bool cmp(const int& a, const int& b) {
    	return a > b;
    }
    int main()
    {
    	vector<int> arr = { 3,4,5,2,4,5,6 };
    	// 1.
    	// sort(arr.begin(), arr.end());
    	
    	// 2.
    	//sort(arr.begin(), arr.end(), cmp);
    
    	// 3. 使用 cpp 定义好的函数  #include <functional>
    	//sort(arr.begin(), arr.end(), greater<int>());
    
    	// 4. 使用自定义的类
    	struct compare
    	{
    		bool operator()(int a, int b) const
    		{
    			return a > b;
    		}
    	};
    	compare my_cmp;
    	sort(arr.begin(), arr.end(), my_cmp);
    
    	for (auto& item : arr)
    		cout << item << ' '; 
    
    	return 0;
    }
    

    map 排序

    template < class Key,                                     // map::key_type
               class T,                                       // map::mapped_type
               class Compare = less<Key>,                     // map::key_compare
               class Alloc = allocator<pair<const Key,T> >    // map::allocator_type
               > class map;
    

    可以看到 map 同 sort 一样,可以传入一个 Compare 类,缺省是 less 如下

    template<class _Ty = void>
    struct less
    {	// functor for operator<
          constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
          {	        // apply operator< to operands
    		return (_Left < _Right);
           }
    };
    

    less 类是个模板类。里面是重载了 operator(),内部的比较是 operator< 实现的。所以如果我们想改变 map 的自动 key 排序方式,就可以传入自定义的比较类。

    key 自定义排序

    #include <map>
    #include <string>
    #include <iostream>
    using namespace std;
    struct Compare  // key 的排序 降序
    {
    	bool operator()(const string& s1, const string& s2) const
    	{
    		return s1 > s2;
    	 }
    };
    int main()
    {
    	map<string, int, Compare> my_set;
    	my_set.insert(make_pair(string("2dx"), 3));
    	my_set[string("6dx")] = 7;
    	my_set["3dx"] = 7;
    	
    	for (auto& item : my_set)
    	{
    		cout << item.first << ' ' << item.second << endl;
    	}
    	return 0;
    }
    
    6dx 7
    3dx 7
    2dx 3
    

    按照value排序

    我们知道 sort 函数只能对顺序容器如 vector, string 排序使用。所以,我们可以换个思路,将 map 先转入到 vecotr 中,再自定义按照 value 排序

    #include <map>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <iostream>
    using namespace std;
     
    typedef pair<string, int> PAIR;
    
    struct 
    {
    	bool operator()(const PAIR& p1, const PAIR& p2)
    	{
    		// 按照 value 降序
    		if (p2.second > p1.second)
    			return true;
    		else if (p2.second > p1.second)
    			return false;
    		else
    		{
    			// 按照 key 升序
    			if (p1.first < p1.first)
    				return true;
    			else
    				return false;
    		}
    	}
    }Compare;
    int main()
    {
    	map<string, int> my_map = {
    		{"3th", 4}, {"2th", 7}, {"1th", 7}
    	};
    
    	vector<PAIR> my_vector;
    	copy(my_map.begin(), my_map.end(), back_inserter(my_vector));
    
    	sort(my_vector.begin(), my_vector.end(), Compare);
    
    	for (auto& item : my_vector)
    	{
    		cout << item.first << ' ' << item.second << endl;
    	}
    
    	return 0;
    }
    
    3th 4
    1th 7
    2th 7
    

    set 排序

    set方式1 重载元素本身<运算符

    但是对于 set map 等本身有序的函数,即在插入的时候,会通过比较元素选择插入的位置,所以我们可以通过重载 operator < 运算符实现自定义排序

    #include <set>
    #include <string>
    #include <iostream>
    using namespace std;
    struct stu
    {
    	string name;
    	int age;
    	bool operator< (const stu& p) const // const必须写.
    	{
    		if (age < p.age)  // 按照 age 降序 
    			return false;
    		else if (age > p.age)
    			return true;
    		else
    		{
    			return name < p.name; // 否则, 按照 name 升序
    		}
    	}
    };
    int main()
    {
    	set<stu> my_set;
    	stu s;
    	my_set.insert(stu{ string("2dx"), 3 });
    	my_set.insert(stu{ string("2dx"), 7 });
    	my_set.insert(stu{ string("3dx"), 7 });
    	
    	for (auto& item : my_set)
    	{
    		cout << item.name << ' ' << item.age << endl;
    	}
    	return 0;
    }
    
    2dx 7
    2dx 7
    2dx 3
    

    set 方式2 传入比较类

    如果我们看 set 定义的方法

    template<
        class Key,
        class Compare = std::less<Key>,
        class Allocator = std::allocator<Key>
    > class set;
    

    可以看到其实 set 会有内置的比较方法,所以,除了对类方法进行重载,我们还可以传入一个比较函数。也就类似于 sort function 中的 cmp

    #include <set>
    #include <string>
    #include <iostream>
    using namespace std;
    struct stu
    {
    	string name;
    	int age;
    };
    struct Compare
    {
    	bool operator()(const stu& p1, const stu& p2)
    	{
    		if (p1.age < p2.age)  // 按照 age 降序 
    			return false;
    		else if (p1.age > p2.age)
    			return true;
    		else
    		{
    			return p1.name < p2.name; // 否则, 按照 name 升序
    		}
    	}
    };
    int main()
    {
    	set<stu, Compare> my_set;
    	stu s;
    	my_set.insert(stu{ string("2dx"), 3 });
    	my_set.insert(stu{ string("2dx"), 7 });
    	my_set.insert(stu{ string("3dx"), 7 });
    	
    	for (auto& item : my_set)
    	{
    		cout << item.name << ' ' << item.age << endl;
    	}
    	return 0;
    }
    
    2dx 7
    3dx 7
    2dx 3
    
    ============ 当我沉默时,我觉得充实。当我开口说话时,却觉得空虚 ===========
  • 相关阅读:
    华为预测服务新版本上线!自定义预测轻松满足您的个性化需求
    HMS Core华为分析丨受众细分,多场景促进精益运营
    关注推送数据报告、消息回执功能,提高推送效率
    快应用tabs和video组件滑动事件优先级问题
    视频播放如何更安全流畅?看南非影音娱乐DStv Now App集成系统完整性检测&应用安全检测功能!
    华为联运游戏或应用审核驳回:HMS Core升级提示语言类型错误
    路径偏移定位不准确?华为定位SuperGNSS技术帮您解决这一难题!
    如何在Flutter中集成华为认证服务
    Oracle定时存储过程
    国家气象局提供的天气预报接口
  • 原文地址:https://www.cnblogs.com/KongHuZi/p/13822358.html
Copyright © 2011-2022 走看看