stl map与multimap的使用
map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
multimap:允许关键值重复,重复的关键值可以有不同的val,map不允许关键值重复。
C++ map是一种关联式容器,包含“关键字/值”对
头文件
#include<map>
变量定义
map<int,int> m;
主要函数
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
lower_bound() 返回键值>=给定元素的第一个位置
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
upper_bound() 返回键值>给定元素的第一个位置
实例一
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<int,string> map1;//定义
map1[13]="beijing";//添加元素key:13,val:beijing
map1.insert(map<int,string>::value_type(2,"xian"));//添加元素key:2,val:xian
map1.insert(pair<int,string>(1,"china"));
map1.insert(make_pair<int,string>(4,"V5"));
map<int,string>::iterator it;
//map自动按key的值进行排序
for (it=map1.begin();it!=map1.end();it++)
{
cout<<it->first<<":"<<it->second<<" ";
}
cout<<endl<<"-------"<<endl;
map1[13]="this";//修改key为13val为this
map1.insert(pair<int,string>(1,"China"));//不会修改key为1的val
map1.insert(make_pair<int,string>(4,"V6")); //不会修改
map1.insert(map<int,string>::value_type(2,"Xian"));//不会修改
for (it=map1.begin();it!=map1.end();it++)
{
cout<<it->first<<":"<<it->second<<" ";//it->first获取key的值,it->second获取val的值
}
cout<<endl<<"-------"<<endl;
cout<<map1.find(1)->second<<endl;
//cout<<map1.find(19)->second<<endl; 注意这里没有key为19的值,故运行时会出错
//因此查找key的val值正确的做法应为
it=map1.find(19);
if(it==map1.end())
{
cout<<"No found"<<endl;//没有查找成功时
}
else
{
cout<<it->second<<endl;
}
it=map1.find(1);
if(it==map1.end())
{
cout<<"No found"<<endl;//没有查找成功时
}
else
{
cout<<it->second<<endl;
}
it=map1.lower_bound(2);
if (it!=map1.end())
{
cout<<it->first<<":"<<it->second<<endl;
}
it=map1.upper_bound(2);
if (it!=map1.end())
{
cout<<it->first<<":"<<it->second<<endl;
}
map1.erase(2);
for (it=map1.begin();it!=map1.end();it++)
{
cout<<it->first<<":"<<it->second<<" ";//it->first获取key的值,it->second获取val的值
}
cout<<endl<<"-------"<<endl;
map1.erase(8);
for (it=map1.begin();it!=map1.end();it++)
{
cout<<it->first<<":"<<it->second<<" ";//it->first获取key的值,it->second获取val的值
}
cout<<endl<<"-------"<<endl;
return 0;
}
实例二
1)根据要删除的键值对位于容器中的位置,实现删除该键值对。
//删除map容器种指定位置的键值对
iterator erase(const_iterator position);
其中,position为迭代器,指向要删除的键值对。
该方法会返回一个iterator迭代器,其指向的是删除键值对之后的那个键值对(如果是删除最后一个键值对,那么该方法也会返回迭代器指向的最后一个键值对之后的位置)。
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
//创建并初始化map容器
map<string,int> myMap{{"penny",1},{"leonard",2},{"sheldon",3},{"howard",4}};
cout<<myMap.size()<<endl; //输出键值对个数
//遍历map容器
for(auto iter = myMap.begin(); iter != myMap.end(); iter++){
cout<<iter->first<<","<<iter->second<<" ";
}
cout<<endl;
//创建一个指向要删除键值对的迭代器
map<string,int>::iterator iter = ++myMap.begin(); //指向第二个键值对
//执行删除操作
map<string,int>::iterator ret = myMap.erase(iter);
cout<<myMap.size()<<endl; //输出键值对个数
//输出erase()方法返回的迭代器指向的键值对
cout<<ret->first<<" "<<ret->second<<endl;
return 0;
}
实例三
2)传入要删除目标键值对的键的值,该方法会自行根据指定的键找到目标键值对,并将其删除。
//删除map容器种键为k的键值对
size_type erase(const key_type& k);
其中,参数k为要删除的键值对的键的值。
该方法的返回值为成功删除的键值对的个数。由于map容器种每个键值对的键都是独一无二的,故其返回值最大为1.
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
//创建并初始化map容器
map<string,int> myMap{{"penny",1},{"leonard",2},{"sheldon",3},{"howard",4}};
cout<<myMap.size()<<endl; //输出键值对个数
//执行删除操作,删除myMap容器种键为"penny"的键值对
int num = myMap.erase("penny");
cout<<myMap.size()<<endl; //输出键值对个数
//输出erase()方法的返回值
cout<<"num= "<<num<<endl;
return 0;
}
实例四
3)在某些情况下,可能需要删除某个指定区域内的所有键值对,也可以通过erase()方法实现。
//删除 map 容器中位于 [first,last) 区域内的所有键值对
iterator erase (const_iterator first, const_iterator last);
其中参数first和last都是迭代器,[first, last)就表示map容器种的某个范围,该方法会删除此范围内的所有键值对。
返回值为一个迭代器,其指向删除范围之后的第一个键值对。如果该范围之后,不再有任何键值对,则返回的迭代器指向map容器最后一个键值对之后的位置。
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
//创建并初始化map容器
map<string,int> myMap{{"penny",1},{"leonard",2},{"sheldon",3},{"howard",4}};
cout<<myMap.size()<<endl; //输出键值对个数
//指定范围
map<string,int>::iterator first = myMap.begin();
map<string,int>::iterator last = --myMap.end();
//删除指定范围内的容器
map<string,int>::iterator ret = myMap.erase(first,last);
cout<<myMap.size()<<endl;
cout<<ret->first<<" "<<ret->second<<endl;
return 0;
}
实例五:
insert插入相同键值时不会改变原有的值
#include<bits/stdc++.h>
using namespace std;
map<int,int> ma;
int main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
ma.insert(pair<int,int> (x,y)); //插入相同键值的时候不会改变
map<int,int>::iterator it;
for (it=ma.begin();it!=ma.end();it++)
{
cout<<(it->first)<<" "<<(it->second)<<endl;
}
cout<<"----"<<endl;
}
}
/*
in
8
4 5
4 3
1 2
3 7
3 8
8 9
4 0
5 6
out
8
4 5
----
4 5
----
1 2
4 5
----
1 2
3 7
4 5
----
1 2
3 7
4 5
----
1 2
3 7
4 5
8 9
----
1 2
3 7
4 5
8 9
----
1 2
3 7
4 5
5 6
8 9
----
*/
使用数组形式可以改变原有的值
#include<bits/stdc++.h>
using namespace std;
map<int,int> ma;
int main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
ma[x]=y; //数组方式可以修改原有的值
map<int,int>::iterator it;
for (it=ma.begin();it!=ma.end();it++)
{
cout<<(it->first)<<" "<<(it->second)<<endl;
}
cout<<"----"<<endl;
}
}
/*
in
8
4 5
4 3
1 2
3 7
3 8
8 9
4 0
5 6
out
4 5
----
4 3
----
1 2
4 3
----
1 2
3 7
4 3
----
1 2
3 8
4 3
----
1 2
3 8
4 3
8 9
----
1 2
3 8
4 0
8 9
----
1 2
3 8
4 0
5 6
8 9
----
*/
multimap不支特数组的插入形式
map使用结构体的实例
//当元素为结构体时自定义排序
#include <iostream>
#include <map>
#include <utility>
using namespace std;
struct Info
{
string name;
float score;
//重载"<"操作符,自定义排序规则
bool operator < (const Info &a) const
{
if(score==a.score)
return name>a.name;
return score>a.score;
}
};
int main()
{
map<Info,int> m;
Info info;
info.name="Jack";
info.score=60;
m[info]=25;
info.name="Tom";
info.score=60;
m[info]=30;
info.name="Bomi";
info.score=80;
m[info]=10;
info.name="Peti";
info.score=66.5;
m[info]=30;
map<Info,int>::iterator it;
for(it=m.begin();it!=m.end();it++)
{
cout<<(*it).second<<" : ";
cout<<((*it).first).name<<" "<<((*it).first).score<<endl;
}
return 0;
}
浙公网安备 33010602011771号