目录
一. 基本性质
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;
}