STL容器-Map and Pair(一)

map介绍:

1.map翻译为映射,是STL中的常用容器也是STL的一个关联容器,它提供一对一的数据处理能力。什么是一对一的数据处理能力呢,像我们查字典,我们可以从开头处找到这个单词对应的页数,从而通过页数找到单词,那么页数-单词就形成了一 一对应的关系。
2.一维map的定义为
map< typename1,typename2 > name,
其中,typename1是映射前的类型(键key),typename2是映射后的类型(值value),其中的键和值不同于数组,只能将一种有限的类型映射到另一种有限的类型,像int a[10]就是将int类型映射到int类型,map可以map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器),当然键和值必须是唯一的。

map的使用范围

1)需要建立字符(串)与整数之间的映射,使用 map 可以减少代码量。
2)判断大整数(比如几千位)或者其他类型数据是否存在,可以把map当布尔型数组使用(哈希表),因为在主函数外部被定义的变量若不赋值,编译器会自动赋值为0.
3)字符串与字符串之间的映射。

定义以及访问

定义:要使用map,必须先添加map头文件,即#include < map>,
同时必须要有“using namespace std”。
定义一个一维map的方法为:map<typename1,typename2> name;
其中在建立map的同时,会自动按照键(key)的顺序排序。
访问:
访问 map 的元素有两种方式,一种是通过下标访问;另一种是通过迭代器访问。
通过下标访问就像普通的数组元素访问,例如先定义map<sring,int> mp,然后就可以通过mp[break]的方式来访问它对应的元素,如mp[break]=123。
通过迭代器访问,先作如下定义:

map<string,int>vis;
map<string,int>::iterator it;

使用迭代器遍历map的时候,迭代器起始的位置是首元素,但是迭代器的末尾位置是最后一个元素的后一位,所以我们不可以这样写:

for(it=vis.begin();it<=vis.end();it++)

而是要这样写

 for(it=vis.begin();it!=vis.end();it++)

相当于一个左闭右开的区间。
我们用“it->first”来访问键,使用“it->second”来访问值。

map常用的函数:

(1).find()和 .size()
find(key)是返回键为 key 的映射的迭代器,时间复杂度为 0(log 2 n),n 为 map 中映射的对数。size()用来获得map中映射的对数,时间复杂度为O(1)。
(2).clear()
clear()用来清空 map,时间复杂度为 0(n)。
(3).erase()
erase()可以删除单个元素,也可以删除一个区间内的所有元素。
删除单个元素可以用:erase(it),it为要删除的元素的迭代器,时间复杂度为O(1)。
也可以用:erase(key),key为要删除的映射的键,时间复杂度为O(log2n)。
删除一个区间内的所有元素用:erase(first,last),first为区间的起始迭代器,last为区间的末尾迭代器的下一个地址,也就是左闭右开的区间[first,last),时间复杂度为O(last-first)。

Pair介绍:

pair 是“二元结构体”的替代品,将两个元素捆绑在一起,节省编码时间。相当于以下定义:

struct pair
{
   typename1 first;
   typename2 second;
}

Pair的定义及使用

定义:
要使用pair,必须先添加头文件,
即#include < utility >,
同时必须要有“using namespace std”。
因为map的内部实现中涉及pair,因此添加map头文件时会自动添加utility头文件,此时可以省去utility头文件。
pair有两个参数,分别对应first和second的数据类型,可以是任意基本数据类型或者容器。
定义一个pair的方法为:
pair<typename1,typename2> name;
取出pair第一个元素的方法:name.first;
取出pair第二个元素的方法:name.scond;
在这里和map的是不同的!!!
其中pair会自动按照第一个元素从小到大的顺序排序,如果第一个元素的值相同,则会按照第二个元素从小到大的顺序排序。

map的二维表示和迭代器遍(正序/逆序)

1.map与pair嵌套,用pair的二元结构做键。
2.map与map嵌套,创造一个类似于二维数组的map。
示例1:示例来自nefu_ljw
https://blog.csdn.net/ljw_study_in_CSDN/article/details/104355672


using namespace std;
typedef long long ll;
ll n,x,y;
map<pair<ll,ll>,int>vis;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x>>y;
        vis[{x,y}]++;//结构体当下标
    }
    printf("\n正向遍历\n");
    map<pair<ll,ll>,int>::iterator it;
    for(it=vis.begin();it!=vis.end();it++)//正向遍历
        printf("%lld %lld %d\n",it->first.first,it->first.second,it->second);
        //输出x,y,{x,y}出现次数
    printf("反向遍历\n");
    map<pair<ll,ll>,int>::reverse_iterator re_it;//注意反向遍历写的是reverse_iterator
    for(re_it=vis.rbegin();re_it!=vis.rend();re_it++)//反向遍历
        printf("%lld %lld %d\n",re_it->first.first,re_it->first.second,re_it->second);
        //输出x,y,{x,y}出现次数
    return 0;
}
————————————————
版权声明:本文为CSDN博主「nefu_ljw」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ljw_study_in_CSDN/article/details/104355672

示例2:示例来自nefu_ljw
https://blog.csdn.net/ljw_study_in_CSDN/article/details/104355672

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,map<ll,int> >vis;
ll n,x,y;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x>>y;
        vis[x][y]++;
    }
    map<ll,map<ll,int> >::iterator i;
    map<ll,int>::iterator j;
    printf("\n正向遍历\n");
    for(i=vis.begin();i!=vis.end();i++)
        for(j=i->second.begin();j!=i->second.end();j++)
            printf("%lld %lld %d\n",i->first,j->first,j->second);
    map<ll,map<ll,int> >::reverse_iterator re_i;
    printf("反向遍历\n");
    for(re_i=vis.rbegin();re_i!=vis.rend();re_i++)//i需要倒序,j不需要
        for(j=re_i->second.begin();j!=re_i->second.end();j++)
            printf("%lld %lld %d\n",re_i->first,j->first,j->second);
    return 0;
}
————————————————
版权声明:本文为CSDN博主「nefu_ljw」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ljw_study_in_CSDN/article/details/104355672
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值