<STL - 3> 字典 map 与 multimap

一. 介绍

map的介绍

map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对

它提供基于key的快速检索能力

map中key值是唯一的,字典中的元素按一定的顺序排列

map可以直接存取key所对应的value,支持[]操作符,如map[key]=value(将key键所对应的值修改为value

multimap与map的区别:map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符

特点

map<T1, T2> map_name; 这里的容器是键值对类型, 类似python的字典

二. 常用函数

1. 默认构造

①. map语法

map<键的类型, 值的类型> 容器名;

②. multimap语法

multimap<键的类型, 值的类型> 容器名;

注 :

其中键和值的类型还可以用各种指针类型或自定义类型

2. map容器的构造并初始化

map元素的插入 三种方式 :
● 通过pair插入对象:mapStu.insert(pair(键,值) );

● 通过value_type插入对象:mapStu.insert(map<int,string>::value_type(键,值) );

● 类似下标索引插入值:mapStu[键] = 值;

①. 使用pair进行insert构造

语法 : map.insert(…); //往容器插入元素,返回pair

map<int, string> mStu;//构建一个map

//错误示范
mStu.insert(pair(3,"nihao"))//错误, 在pair的初始化是,需要标志参数

//先构造再传入
pair<int, string>  p (3, "nihao")
mStu.insert(p);

//直接传入, 成功的插入
mStu.insert(pair<int, string>(6, "good"));//正确

④. 通过emplace插入元素

//语法 : 字典名.emplace(键, 值);
map<int, string> mStu;

// 使用 emplace 插入新元素
mStu.emplace(1, "A");  // 插入键值对 {1, "A"}
mStu.emplace(2, "B");  // 插入键值对 {2, "B"}

// 替换已存在的键值对
mStu.emplace(1, "C");  // 不会替换,因为键值 1 已经存在

cout << mStu[1];       // 输出 "A"

③. 通过value_type的方式插入对象

//语法 : 
mStu.insert(map<键类型, 值类型>::value_type(,));

//直接初始化value并赋值
mStu.insert(map<int, string>::value_type(5, "hello"));

//先构建value_type 再传入
map<int, string>::value_type v (7, "你好");
mStu.insert(v)

④. 通过数组赋值的方法插入对象


//语法 : 
map名字[键名称] = value;                     // 相当于中括号进行重载了 , 特点会进行覆盖

//例 : 
mStu.insert(pair<int, string>(6, "good"));  //已经插入对象
mStu.insert(pair<int, string>(6, "bad"));   //此处的bad插入失败, 6的值不会被覆盖, 而且会返回一个迭代器指向已存在的元素
mStu[6] = "bad";                            //此处把6的值覆盖成了bad
特点 :

map名字[键] = 值, 作为左值可以改变键对应的值
作为右值可以查找字典中键对应的值
注 : 如果查找的键不存在, 则会自动创建一个键值对, 其中默认为 ’ ’

例 :
string stu_name = mStu[10];//综上没有10这个键, 这里创建了一个
cout << stu_name << endl; //此处输出一个 ' ' , 空字符

总结 : 方法③直观,但存在性能的问题 : 如果键存在则修改,如果不存在则插入

3. 与map的大小有关的函数

①. size()

语法 :

字典名.size(); // 返回元素的个数

②. empty()

语法:

字典名.empty(); // 判断字典容器是否为空, 是则返回1. 否则返回0
(常用 : !map.empty())

4. map中元素的删除

①. clear() (清空)

语法 :

字典名.clear() //删除所有元素

②. erase() (有返回值删除)

语法1 :

字典名.erase(左迭代器,右迭代器); //删除区间[左迭代器,右迭代器)的所有元素, 返回end()的迭代器

语法2 :

字典名.erase(迭代器); // 删除迭代器所指向的元素, 删除后返回下一个元素的迭代器

语法3 :

字典名.erase(键); // 删除字典容器中key对应的键值对, 删除成功后返回删除元素的个数,如果有多个则删除所有键值对等于给定键的键值对

注 :

如果是map则是1, 在multimap中可能会返回大于1的值

5. map中元素的排序规则

默认情况 , map 中元素的排序规则是以升序方式进行排列的, 所以键值小的元素会排在前面

但multimap中的键可以重复, 不一定可以按照特定顺序

6. map中元素的查找

①. find()

语法 : 字典名.find(; )// 成功返回对应查找到的迭代器,迭代器是指向pair, 可以通过解引用后用’.', 或者**直接用迭代器->**访问迭代器指向的pair中的键值对

, 失败则返回迭代器字典名.end()

②. at()

语法 : 字典名.(); // 成功返回传入键对应的值, 如果键值不存在就抛出out of range异常

注 : 常用find()代替, 通过

if (p.second != mStu.end())
        cout << "euqle_range: first:" << p.first->first << " second:" << (p.second--)->second << endl;
else cout << "key not found" << endl;

③. count()

语法: 字典名.count(); // 返回容器中key为keyElem的对组个数

④. lower_bound()

语法 : 字典名.lower_bound(elem); //返回第一个>=elem元素的迭代器

⑤. upper_bound()

语法 : 字典名.upper_bound(elem); // 返回第一个>elem元素的迭代器

⑥. equal_range()

语法 : 字典名.equal_range(elem); //返回容器中与elem相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end), 注意返回的是两个迭代器, 但是封装在一个pair中,所以①. auto, ②. 一个pair中两个map的迭代器类型

例 :
#include <iostream>
#include <map>
using namespace std;

int main()
{
        map<int, string> mStu;
        //插入 1-6
        mStu.emplace(1, "good");

        pair<int, string> p1(2, "bad");
        mStu.insert(p1);
        mStu.insert(pair<int, string>(3, "python"));

        mStu[4] = "hello";

        map<int, string>::value_type v1(5, "c");
        mStu.insert(v1);
        mStu.insert(map<int, string>::value_type(6, "people"));

        //查找1-6
         map<int, string>::iterator it1 = mStu.find(1);//注意返回的是迭代器,迭代器指向的是pair,piar中存放的是一个key一个value(要么解引用后用'.', 要么直接用迭代器->)
         string name2 = mStu.at(2);//at只返回查到键对应的值
         int n = mStu.count(3);//返回存在键为3的对组数, 在map中可以作为检测存在的函数, 在mlutimap中查找存在得个数
         map<int, string>::iterator it2 = mStu.lower_bound(4);//第一个大于等于的迭代器, 在这则返回指向4的迭代器
         map<int, string>::iterator it3 = mStu.upper_bound(5);//第一个大于的迭代器, 在这里则返回指向6的迭代器
         pair<map<int, string>::iterator, map<int, string>::iterator> p = mStu.equal_range(6);//返回的pair中存放的是两个迭代器, beg和end, 所以pair<>尖括号中的类型是两个map的迭代器
         //巧的是,此处返回的值6和6后面的元素的迭代器
         
         //string name3 = mStu.at(7);//不存在则报错
         //perror("at");

         cout << "find(1):" << "second : " << it1->second << "first : " <<it1->first<< endl;//first是键, seconds是值
         cout << "at(2): :" << name2 << endl;
         cout << "count(3) : " << n << endl;
         cout << "lower_bound: " << it2->second <<"first : " << it2->first << endl;//这里可以看出两个东西指向的位置是哪
         cout << "upper_bound: " << it3->second << "first : " <<it3->first<< endl;
         cout << "euqle_range: first:" << p.first->first << " second:" << (--p.second)->second << endl;//equal_range 函数返回值是一个 pair 对象,其中的 first 和 second 成员都是迭代器,分别指向所匹配键范围的起始位置和结束位置
         //让second像前移一位,指向和beg相同的位置
         if (p.second != mStu.end()) {
                cout << "euqle_range: first:" << p.first->first << " second:" << (p.second--)->second << endl;
         }
         else {
                cout << "key not found" << endl;//此时显示了这句话
         }
         return 0;
}

7. map中的交换函数

语法 :
字典名.swap(mp); //交换两个集合容器

例 :
//使用上面的字典
         map<int, string> m1;
         m1.insert(map<int,string>::value_type (0, "nan"));

         mStu.swap(m1);//通过监视看到, 此时m1大小为6个元素, mStu大小为一个元素, 交换完成

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值