【C/C++】 STL map 详解

目录

一. 基本性质

1. 基本函数

2. 基本用法

二. 例题分析

1. 问题描述

2. 题解代码


一. 基本性质

        map是一类关联式容器,它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。map会自动建立Key-Value的对应,其中key和value可以是任意你需要的类型。map不允许元素重复(键必须唯一,值可以相同),自动忽略重复元素,默认我们插入<key, value>键值对时就会按照key的大小顺序进行存储!注意对于迭代器来说,可以修改实值,而不能修改key。

1. 基本函数

  • begin():返回指向map头部的迭代器
  • clear():删除所有元素
  • count():返回指定元素出现的次数,s.count(元素)
  • empty():如果map为空则返回true
  • end():返回指向map末尾的迭代器
  • erase():删除一个元素。注意括号里为迭代器,erase(pos)与erase(begin,end)两种,返回值都是一个迭代器,该迭代器指向被删除元素后面的元素
  • find():查找一个元素。find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。例如下:
map<int ,string >::iterator l_it;
l_it=maplive.find(112);
if(l_it==maplive.end())
    cout<<"we do not find 112"<<endl;
else cout<<"wo find 112"<<endl;
  • insert():插入元素
  • lower_bound():返回键值>=给定元素的第一个位置
  • size():返回map中元素的个数
  • swap():交换两个map
  • upper_bound():返回键值>给定元素的第一个位置

2. 基本用法

(1)数据插入

        因为map为有序集合,所以map、set均不支持push_back函数而只能用insert或者下标两种方式插入数据。

  • 用insert函数插入make_pair数据
#include <iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
    map<string,int> itoa;
    itoa.insert(make_pair("wangxin",9));
    itoa.insert(make_pair("mengyuan",9));
    itoa.insert(make_pair("zaiyiqi",99));
    map<string,int>::iterator it;
    for(it=itoa.begin(); it!=itoa.end(); it++)
        cout<<it->first<<"\t"<<it->second<<endl;

    return 0;
}
  • 用数组方式插入数据,直接赋值。
#include <iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
    map<string,int> itoa;
    itoa.insert(make_pair("wangxin",9));
    itoa.insert(make_pair("mengyuan",9));
    itoa.insert(make_pair("zaiyiqi",99));
    itoa["my"]=6;//之间引用数组下标方式赋值插入
    itoa["wx"]=66;
    map<string,int>::iterator it;
    for(it=itoa.begin(); it!=itoa.end(); it++)
        cout<<it->first<<"\t"<<it->second<<endl;

    return 0;
}

(2)map的大小

        在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:

int nSize = mapStudent.size();

(3)map的遍历

        map的遍历可以用迭代器iterator,然后用first和second来遍历键值对;除此之外,也可以通过数组下标的方式遍历数据。

(4)判定数据是否存在

        用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了。

二. 例题分析

1. 问题描述

Problem Description
输入一些单词(以“#”为结束标志),找出所有满足如下条件的单词:该单词不能通过字母的重排,得到输入文本中的另一个单词。在判断是否满足条件是不分大小写,但是在输出时应保留输入时的大小写,按字典序进行排列(所有大写字母在所有小写字母前面)。

Sample input

ladder came tape soon leader acme RIDE lone Dreis peat
ScAlE orb  eye  Rides dealer  NotE derail LaCeS  drIed
noel dire Disk mace Rob dries
#

Sample output

Disk

NotE

derail

drIed

eye

ladder

soon

2. 题解代码

        首先如何判断单词是否能通过重排得到另一个单词呢?其实只要两单词长度一样,字母出现次数一样(不区分大小写)即可判定。那么怎么判断字母出现次数一样呢?可以将所有单词自己按照字典序排序字母,如果有两个strcmp一样即为可以通过重排。

        其次将每个单词标记为(x,y),x为其标准化后的字符串(全部变为小写且排序完成),y为其标准化单词出现次数。如果y出现大于一次·,则不存入容器,最后输出容器即可!注意利用map的映射关系以及set自动排序型以及忽略重复性。

#include <iostream>
#include<map>
#include<string>
#include<vector>
#include<algorithm>
#include<cctype>
using namespace std;
map<string,int>cnt;
vector<string>word;
string repr(string &ss)//标准化函数
{
    string ans=ss;
    for(int i=0;i<ans.size();i++)
    {
        ans[i]=tolower(ans[i]);//全部小写
    }
    sort(ans.begin(),ans.end());//排序
    return ans;//标准化完成
}
int main()
{
    string s;
    while(cin>>s)
    {
        if(s[0]=='#')break;
        word.push_back(s);
        string r=repr(s);
        if(cnt.count(r)==0)cnt[r]=0;//没出现过初始化map键对应值为0
        cnt[r]++;
    }
    vector<string> it;
    for(int i=0;i<word.size();i++)
    {
        if(cnt[repr(word[i])]==1)//出现一次
            it.push_back(word[i]);//存入
    }
    sort(it.begin(),it.end());//排序
    for(int j=0;j<it.size();j++)
    {
        cout<<it[j]<<endl;//输出
    }
    return 0;
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿阿阿安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值