zoukankan      html  css  js  c++  java
  • STL 中 map 的使用

    涉及:vector,pair

    基本结构

    map 从本质上来说是一颗二叉排序树,树上的节点类型为pair。pair类型中有两个重要的成员变量,其中 first 存储了 key ,second 存储了 value。

    特性

    map中的每一个键都是唯一的。即一个键只能对应一个值。
    map中的值总是按序排列。
    map中查找元素只能根据 key 来查找。

    头文件

    #include<map>
    
    using namespace std;
    

    声明与定义

    map<[键类型],[值类型]> [变量名]; //默认按照 key 升序排列顺序存储
    map<[键类型],[值类型],greater<值类型> > [变量名]; //支持定义了 '>' 运算符的类型,对 key 降序排列 // 注意后面两个尖括号之间要有空格

    举例:

    map<string,int> m;
    map<MyType,string,greater<MyType> > m1; // MyType 是自己定义的类型,重载了 '>' 运算符
    

    迭代器

    begin() 返回指向第一个元素的迭代器
    end() 返回指向最后一个元素之后的迭代器

    map 变量的元素范围[ begin(), end() )

    m.begin();
    m.end();
    

    注意:不能对迭代器做加法操作,例如 'm.begin() + 5' 是错误的。

    容量

    size() 返回map中元素的个数;

    size();
    

    添加元素

    insert(pair<[键类型],[值类型]>([键对象],[值对象]));
    insert(map<[键类型],[值类型]>::value_type([键对象],[值对象])); // 其实跟上面的赋值方法一模一样的。

    还可以直接使用 '[]' 操作符。

    m.insert( pair<MyType,string>(obj,"binbin") );
    m.insert( map<MyType,string>::value_type(obj,"binbin") );
    
    m[obj] = "binbin";
    

    注意:如果重复插入 key 相同的键值对。那么对于 insert 方式,第一次插入以后的插入均无效;对于 '[]' 方式,每次插入都会将原来的键值对覆盖掉。

    查找元素

    count([键对象]) 判断键值对是否存在,有返回1,无返回0。
    find([键对象]) 查找键对应的值,无论是否存在都返回元素指针(iterator对象)。当元素指针 等于 end() 的返回值时,表示键值对不存在。

    // 方法一
    if (m.count(keyObj)){  // 判断键值对是否存在,有返回1,无返回0
        ValueType val = m[keyObj];
    }
    
    // 方法二
    map<KeyType,ValueType>::iterator i = m.find(keyObj);
    
    if(i != m.end()) 
        ValueType val = i->second;
    

    删除元素

    clear() 清除所有元素
    erase([元素指针]) 通过元素指针删除元素
    erase([键对象]) 通过键删除元素
    erase([起始元素],[结束元素]) 删除[起始元素,结束元素)范围内元素

    m.clear();
    
    m.erase(i);                       // i = m.begin() + 5;
    m.erase(keyObj);                  // 
    m.erase(m.begin(),m.end()); //删除 map 中前5个元素
    
    

    注意:不能对 'map<>::iterator' 对象 做加法操作,例如 'm.begin() + 5' 是错误的。

    更改元素值

    或者先删除原来的元素,再插入;或者找到元素后修改;或者用 [] 赋值。

    仅列举后两种方法:

    m["我是键"] = "我是值";
    
    m.find("我是键")->second = "我是值"; // 上面 [] 方法的实质与本方法相同
    
    

    排序

    按 key 排序

    map 中的元素是默认按照键排好序的,因此,只需要重载键类型的 < (或者 > )操作符即可。

    struct St{
        int a;
        
        bool operator < (const St & b){
            return a < b;
        }
        bool operator > (const St & b){
            return a > b;
        }
    }
    
    map<St,int> m1; // 按照St定义的 < 操作符对map元素进行排序
    map<St,int,greater<St> > m2; // 按照St定义的 > 操作符对map元素进行排序
    

    按 value 排序

    把 map 中的元素都放入到 vector 中后再进行排序,map 中元素的类型为 pair。
    参考的如下代码:

    typedef pair<St,int> PAIR;              // 重定义
    
    bool cmp(const PAIR &a,const PAIR &b){  // 比较函数
    	return a.second > b.second;
    }
    
    vector<PAIR> vec(m1.begin(),m1.end());  // map 元素移交到 vector
    sort(vec.begin(),vec.end(),cmp);        // 排序
    
    

    遍历

    特别注意:遍历的结束条件中的比较运算符是 '!=' 而不是 '<'。

    由于 map 元素类型是 pair,因此取出值的方式为 i->second。

    for(map<int, int>::iterator i = m1.begin(); i != m1.end(); ++i){ 
    		cout << i->second << endl;
    		
    }
    

    代码示例

    #include<map>
    #include<vector> // 按值排序时用到
    #include<iostream> // 输出用到
    
    using namespace std;
    
    typedef pair<int, int> PAIR;
    
    struct ST{
    	int a;
    	
    	bool operator < (const ST &b){
    		return  this->a < b.a;
    	}
    };
    
    bool cmp(const PAIR &a,const PAIR &b){
    	return a.second > b.second;
    }
    
    int main(){
    	map<int, int> m1;
    	
    	m1[5] = 6;
    	m1[4] = 2;
    	m1[3] = 1;
    	
    	////////////////////////////////////////////////////
    	// 删除元素	《《《《《
    	
    	m1.erase(3); //输入 键对象
    	if (m1.count(3) == 0) {
    		cout << "键值对 3:1 被删除" << endl;
    	}
    	
    	m1.erase(m1.begin()); //输入 元素指针
    	cout << "删除当前第一个元素(4,2)后:"<< m1.begin()->second << endl; // 输出 6
    	
    	m1.erase(m1.begin(),m1.end()); //输入 删除范围
    	
    	if(m1.empty()) cout << "map 的元素都被删除了" << endl;
    	
    	cout << endl;
    	////////////////////////////////////////////////////
    	
    	
    	m1[5] = 6;
    	m1[4] = 9;
    	m1[3] = 1;
    	
    	
    	////////////////////////////////////////////////////
    	// 添加元素	《《《《《
    	
    	m1.insert(PAIR(5,4));
    	
    	cout  << "insert方法重复添加键值对(5,4),结果 m1[5]:"<< m1[5] << endl; // 输出 6
    	
    	m1[5] = 3;
    	
    	cout  << "使用 [] 方式添加元素 m1[5]:"<< m1[5] << endl; // 输出 3
    	
    	cout << endl;
    	
    	////////////////////////////////////////////////////
    	// 修改元素	《《《《《
    	
    	
    	m1.find(4)->second = 2; // 原本 m1[5] = 9
    	
    	cout  << "修改元素 m1[4]:"<< m1[4] << endl; // 输出 2
    	
    	
    	cout << endl;
    	
    	////////////////////////////////////////////////////
    	// 查找元素	《《《《《
    	
    	//	当前的键值对情况
    	//	m1[5] = 3;
    	//	m1[4] = 2;
    	//	m1[3] = 1;
    	
    	// 方法一
    	if (m1.count(4)){  // 判断键值对是否存在,存在则输出该值
    		cout << "找到元素 m1[4]:"<< m1[4] << endl;;  //输出 2
    	}
    	
    	// 方法二
    	map<int,int>::iterator i = m1.find(5);
    	
    	if(i != m1.end())
    		cout << "找到元素 m1[5]:" << i->second << endl;; //输出 3
    	
    	cout << endl;
    	////////////////////////////////////////////////////
    	// 遍历	《《《《《
    	
    	//	当前的键值对情况
    	//	m1[5] = 3;
    	//	m1[4] = 2;
    	//	m1[3] = 1;
    	
    	/// 输出 123
    	cout  << "默认按 key 升序排列,遍历map:";
    	for(map<int, int>::iterator i = m1.begin(); i != m1.end(); ++i){ // 注意这里是用 != 标记结束的。
    		cout << i->second;
    		
    	}
    	
    	cout << endl;
    	cout << endl;
    	
    	
    	////////////////////////////////////////////////////
    	// 按值 value 排序 《《《《《
    	
    	//	当前的键值对情况
    	//	m1[5] = 3;
    	//	m1[4] = 2;
    	//	m1[3] = 1;
    	
    	
    	vector<PAIR> vec(m1.begin(),m1.end());
    	sort(vec.begin(),vec.end(),cmp);         // 按 value 降序排列
    	
    	
    	/// 输出 321 // 原本是按 key 升序排列,输出为 123
    	cout  << "按 value 降序排序,遍历map:";
    	for (vector<PAIR>::iterator i = vec.begin();i < vec.end(); ++i) {
    		cout << i->second;
    	}
    	
    	cout << endl;
    	
    }
    

    output:

    键值对 3:1 被删除
    删除当前第一个元素(4,2)后:6
    map 的元素都被删除了
    
    insert方法重复添加键值对(5,4),结果 m1[5]:6
    使用 [] 方式添加元素 m1[5]:3
    
    修改元素 m1[4]:2
    
    找到元素 m1[4]:2
    找到元素 m1[5]:3
    
    默认按 key 升序排列,遍历map:123
    
    按 value 降序排序,遍历map:321
    
  • 相关阅读:
    python软件开发目录规范
    模块与包
    匿名函数的使用
    三元表达式,列表生成式,字典生成式,生成器表达式
    Python函数进阶:生成器的原理及使用
    python迭代器的原理及应用
    PYTHON装饰器用法及演变
    文件操作补充
    pycharm的断点调试与TODO标记
    字符编码补充
  • 原文地址:https://www.cnblogs.com/tangyikejun/p/4220316.html
Copyright © 2011-2022 走看看