1.基本介绍
- map提供了“[]”运算符,使得map可以像数组一样使用,所以map也称为
“关联数组"
。 - map使用平衡二叉树管理元素

- map是从键(key)到值(value)的映射,即(key,value),其中key和value可以是任意类类型;
- 必须包含头文件
#include <map>
; - 根据元素的key自动对元素排序,因此根据元素的key进行定位很快,但根据元素的value定位很慢;
- 不能直接改变元素的key,但是可以通过operator []直接存取元素值;
- map不允许key相同的元素,multimap允许key相同的元素;

复杂度
由于底部使用红黑树实现的,所以大部分操作的复杂度都接近
O
(
l
o
g
n
)
O(logn)
O(logn).
操作 | 复杂度 |
---|
插入insert() | O(logn) |
删除erase() | O(logn) |
查找find() | O(logn) |
2.map/multimap的基本方法
2.1 构造、拷贝和析构
操作 | 含义 |
---|
map c | 产生空的map |
map c1(c2) | 产生同类型的c1,并复制c2的所有元素 |
map c(op) | 以op为排序准则产生一个空的map |
map c(beg,end) | 以区间[begin,end)内的元素产生一个map |
map c(beg,end,op) | 以op为排序准则,以区间[begin,end)内的元素产生一个map |
~map() | 销毁所有元素并释放内存 |
其中map的类模板可以是下列形式:
map<key,value> 一个以less(<)为排序准则的map
map<key,value,op> 一个以op为排序准则的map
2.2 非变动性操作
操作 | 含义 |
---|
c.size() | 返回元素个数 |
c.empty() | 判断容器是否为空 |
c.max_size() | 返回容器最大容纳数据的数量(固定值) |
2.3 赋值操作
操作 | 含义 |
---|
c1 = c2 | 将c2的全部元素赋值给c1 |
c1.swap(c2) | 将c1和c2元素互换 |
swap(c1,c2) | 同上,全局函数 |
2.4 特殊搜寻操作
操作 | 含义 |
---|
count(key) | 返回"键值等于key"的元素个数 |
find(key) | 返回"键值等于key"的第一个元素,找不到返回end() |
lower_bound(key) | 返回"键值大于等于key"的第一个元素 |
upper_bound(key) | 返回"键值大于key"的第一个元素 |
equal_range(key) | 返回"键值等于key"的元素区间 |
2.5 迭代器相关函数
操作 | 含义 |
---|
c.begin() | 返回一个迭代器,指向第一个元素(即是指向第一个数据的一个指针) |
c.end() | 返回一个迭代器(指针),指向最后一个元素的下一个位置(实际不存在) |
c.rbegin() | 返回一个逆向迭代器,指向逆向遍历的第一个元素 |
c.rend() | 返回一个逆向迭代器,指向最后一个元素 |
2.6 插入(insert)元素
操作 | 含义 |
---|
c.insert(pos,elem) | 在pos位置插入一个elem拷贝,传回新数据位置 |
c.insert(elem) | 插入elem的副本,并返回新元素的位置 |
c.insert(beg,end) | 将区间[beg,end)内的所有元素的副本插入到c中 |
2.7 移除元素
操作 | 含义 |
---|
c.erase(pos) | 删除迭代器pos所指位置的元素,无返回值 |
c.erase(val) | 移除所有值为val的元素,返回移除元素的个数 |
c.erase(beg,end) | 删除[beg,end)区间的元素,无返回值 |
c.clear() | 移除容器中所有数据,清空容器 |
2.8 示例代码
#include <iostream>
#include <map>
#include <string>
using namespace std;
void showmap(map<string, int> v)
{
for (map<string, int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << it->first << " " << it->second << endl;
}
cout << endl;
}
int main()
{
map<string, int> m1;
m1["Kobe"] = 100;
m1["James"] = 99;
m1["Curry"] = 98;
string s("Jordan");
m1[s] = 90;
cout << m1["Kobe"] << endl;
cout << m1["Jordan"] << endl;
cout << m1["Durant"] << endl;
m1.erase("Curry");
showmap(m1);
m1.insert(pair<string, int>("Harris", 89));
showmap(m1);
if(m1.count("Lee")) cout << "Lee is in m1!" << endl;
else cout << "Lee do not exist!" << endl;
m1.clear();
system("pause");
return 0;
}
输出结果:
100
90
0
Durant 0
James 99
Jordan 90
Kobe 100
Durant 0
Harris 89
James 99
Jordan 90
Kobe 100
Lee do not exist!
请按任意键继续. . .
3.应用
例题:反片语
输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本中的另外一个单词。
在判断是否满足条件时,字母不分大小写,但在输入时应保留输入中的大小写,按字典序进行排列(所有大写字母在小写字母的前面)
样例输入:
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
样例输出:
Disk
NotE
derail
drIed
eye
ladder
soon
解题代码:
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <vector>
#include <string>
#include <cctype>
using namespace std;
map<string, int> mapp;
vector<string> words;
string standard(const string &s) {
string t = s;
for (int i = 0; i < t.length(); i++) {
t[i] = tolower(t[i]);
}
sort(t.begin(), t.end());
return t;
}
int main() {
string s;
while (cin >> s) {
if (s[0] == '#')
break;
words.push_back(s);
string r = standard(s);
if (!mapp.count(r))
mapp[r] = 0;
mapp[r]++;
}
vector<string> ans;
for (int i = 0; i < words.size(); i++) {
if (mapp[standard(words[i])] == 1)
ans.push_back(words[i]);
}
sort(ans.begin(), ans.end());
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] << endl;
}
return 0;
}
参考资料
1.柳婼 の blog
https://www.liuchuo.net/archives/178
2. 2.8示例代码来自博客:C++ STL快速入门
https://www.cnblogs.com/skyfsm/p/6934246.html