对于map关于键与值的排序,对于map的值自定义比较器

1.什么是pair

pair是一种简单的关联类型,不属于容器范围。而是代表一个 key-value键值对。

创建、初始化 示例代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;
//将pair放入容器&initpair
int main(int argc, const char *argv[])
{
    
	//
    pair<string, int> p1;//num.1

    p1.first = "hello";
    p1.second = 12 ;
	//
    pair<string, int> p2("world", 22);//num.2
    
}

2.什么是map?

map

1):map则是一个容器里面存储的是 pair对象。但存储的方式与vector这种 连续存储有所不同, map采用的是 二叉排序树存储pair,一般是红黑树。

2):map使用下标访问时,如果 key不存在,那么会在map 中自动添加一个新的pair,value为默认值。

性能分析:由于map采用二叉排序树(红黑树),树的高度不超过 [logN] +1。所以 插入和查询时间复杂度 为 O(lgN);

注意:使用insert插入map元素时,如果失败,则不会更新原来的值。

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
//Red_black Tree
int main(int argc, const char *argv[])
{
    map<string, int> m;
    m["beijing"] = 2000;
    m["hangzhou"] = 880;
    m["shanghai"] = 1500;
// key --> value  采用二叉排序树对key排序
//两种打印方式
	//way 1
    for(map<string, int>::const_iterator it = m.begin();
        it != m.end();
        it++)
    {
        //*it pair
        cout << it->first <<":" << it->second << endl;
    }
    //way 2
    for(const pair<int, string> &p: m) // -std=c++0x(C++11) 注意要用pair
        cout << p.first << ":" << p.second << endl;
    return 0;
}

3.对有序map中的key排序

如果在有序的map中,key是int,或者string,它们天然就能比较大小,本身的就是有序的。不用额外的操作。

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include <vector>
#include<string>
#include<map>
#include <functional> // std::greater
using namespace std;


struct CmpByKeyLength {
    bool operator()(const string& k1, const string& k2)const {
        return k1.length() < k2.length();
    }
};

int main()
{
    //1、map这里指定less作为其默认比较函数(对象),就是默认按键值升序排列
    // map<string, int> name_score_map;

    // 2、可以自定义,按照键值升序排列,注意加载 
    // #include <functional> // std::greater
    // map<string, int, greater<string>> name_score_map;

    //3、按照自定义内容进行排序,比如字符串的长度
    map<string, int, CmpByKeyLength> name_score_map;

    name_score_map["LiMin"] = 90;
    name_score_map["ZiLinMi"] = 79;
    name_score_map["BoB"] = 92;
    name_score_map.insert(make_pair("Bing", 99));
    name_score_map.insert(make_pair("Albert", 86));

    map<string, int>::iterator iter;
    for ( iter = name_score_map.begin();iter != name_score_map.end();++iter) {
        cout << (*iter).first << endl;
    }

    system("pause");
    return 0;
}

4.对有序map中的value排序

这里就需要上文提到的pair
将map注入vector,如下

	vector<pair<string, int>> v(myMap.begin(), myMap.end());

重写比较器 comparator 如下

//升序
bool myCmp2( pair<string, int> &a,  pair<string, int> &b) {
	return a.second < b.second;
}
//降序
bool myCmp3(const pair<string, int> &a, const pair<string, int> &b) {
	return a.second > b.second;
}

完整代码如下

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<string>
#include<map>
#include <functional> // std::greater
using namespace std;
bool myCmp1(const pair<string, int> &a, const pair<string, int> &b) {
	return a.second < b.second;
}

bool myCmp2( pair<string, int> &a,  pair<string, int> &b) {
	return a.second < b.second;
}
bool myCmp3(const pair<string, int> &a, const pair<string, int> &b) {
	return a.second > b.second;
}


int main() {
	map<string, int> myMap;
	int t = 5;
	string str;
	int tmp;
	while (t--) {
		cin >> str >> tmp;
		myMap[str] = tmp;
	}
	vector<pair<string, int>> v(myMap.begin(), myMap.end());
	sort(v.begin(), v.end(), myCmp1);
	sort(v.begin(), v.end(), myCmp3);
	cout << "test" << endl;

}

测试用例

a 5
f 4
c 10
d 22
u 42

cmp3排序后

  •   [0]	("u", 42)	std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int>
    
  •   [1]	("d", 22)	std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int>
    
  •   [2]	("c", 10)	std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int>
    
  •   [3]	("a", 5)	std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int>
    
  •   [4]	("f", 4)	std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int>
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值