1、map简介
map(映射)是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。对于迭代器来说,可以修改实值,而不能修改key。map提供了很好的一对一关系,在一些程序中建立一个map可以起到事半功倍的效果。
2、map的功能
自动建立Key - value的对应。key 和 value可以是任意你需要的类型。
根据key值快速查找记录,查找的复杂度基本是log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。
快速插入Key -Value 记录。
快速删除记录
根据Key 修改value记录。
遍历所有记录。
3、使用map
使用map要包含map类所在的头文件(#include <map>) 要命名限定std::map
map对象是模板类,需要关键字和存储对象两个模板参数:
map<int, string> isMap;
这样就定义了一个用int作为索引,并拥有相关联的指向string的指针。
构造最基本的map:
map<string , int >siMap map<int ,string >isMap;
map<sring, char>scMap map<char ,string>csMap;
map<char ,int>ciMap map<int ,char >icMap;
4、在map中插入元素
改变map中的条目非常简单,因为map类已经对[]操作符进行了重载
isMap[1] = "One";
isMap[2] = "Two";
.....
这样非常直观,但存在一个性能的问题。插入2时,先在isMap中查找主键为2的项,没发现,然后将一个新的对象插入isMap,键是2,值是一个空字符串,插入完成后,将字符串赋为"Two"; 该方法会将每个值都赋为缺省值,然后再赋为显示的值,如果元素是类对象,则开销比较大。我们可以用以下方法来避免开销:
isMap.insert(map<int, string> ::value_type(2, "Two"))
向map中添加数据:
map<int ,string> isMap;
(1). isMap[1]="One"; //map中最简单最常用的插入添加!
(2). isMap.insert(map<int,string>::value_type(2,"Two"));
(3). isMap.insert(pair<int,string>(3,"Three"));
5、查找并获取map中的元素
下标操作符给出了获得一个值的最简单方法:
string tmp=isMap[2];
但是,只有当map中有这个键的实例时才对,否则会自动插入一个实例,值为初始化值。因此可以使用find()和count()方法来发现一个键是否存在。查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()和end()两个成员,分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator。
map<int,string>::iterator it;
it=isMap.find(1); //要查找的key(此处为1)
if(it==isMap.end())
cout<<"we do not find it"<<endl;
else
cout<<"we find it"<<endl;
find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。
通过map对象的方法获取的iterator数据类型是一个std::pair对象,包括两个数据 iterator->first 和 iterator->second 分别代表关键字和存储的数据。
6、从map中删除元素
移除map中某个条目用erase()
该成员方法的定义如下:
iterator erase(iterator it); //通过一个条目对象删除
iterator erase(iterator first, iteratorlast); //删除一个范围
size_type erase(const Key& key); //通过关键字删除
clear()就相当于isMap.erase(isMap.begin(), isMap.end());
map<int,string>::iterator it;
it=isMap.find(1);
if(it==isMap.end())
cout<<"we do not find it"<<endl;
else
isMap.erase(it); //delete 1;
注意:
map中的swap不是一个容器中的元素交换,而是两个容器交换。
map中的元素是自动按key升序排序,所以不能对map用sort函数。
总结:
begin() 返回指向map头部的迭代器
end() 返回指向map末尾的迭代器
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
insert() 插入元素
find() 查找一个元素
size() 返回map中元素的个数
max_size() 返回可以容纳的最大元素个数
erase() 删除一个元素
clear() 删除所有元素
count() 返回指定元素出现的次数
swap() 交换两个map
empty() 如果map为空则返回true
equal_range() 返回特殊条目的迭代器对
get_allocator() 返回map的配置器
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
实例:
#include <iostream>
#include <string>
#include <map>
using namespace std;
void map_insert(map < string, string > *mapStudent, string index, string x)
{
mapStudent->insert(map < string, string >::value_type(index, x));
}
int main(int argc, char **argv)
{
char tmp[32] = "";
map<string,string> mapS;
map_insert(&mapS, "192.168.0.128", "xiong"); //insert element
map_insert(&mapS, "192.168.200.3", "feng");
map_insert(&mapS, "192.168.200.33", "xiongfeng");
map<string,string>::iterator iter;
cout << "We Have Third Element:" << endl;
cout << "-----------------------------" << endl;
iter = mapS.find("192.168.0.33"); //find element
if(iter != mapS.end())
{
cout << "find the elememt" << endl;
cout << "It is:" << iter->second << endl;
}
else
cout << "not find the element" << endl;
for (iter = mapS.begin(); iter != mapS.end(); iter ) //see element
{
cout << "| " << iter->first << " | " << iter->
second << " |" << endl;
}
cout << "-----------------------------" << endl;
map_insert(&mapS, "192.168.30.23", "xf");
cout << "After We Insert One Element:" << endl;
cout << "-----------------------------" << endl;
for(iter=mapS.begin();iter!=mapS.end();iter)
{
cout << "| " << iter->first << " | " << iter->
second << " |" << endl;
}
cout << "-----------------------------" << endl;
iter = mapS.find("192.168.200.33"); //delete element
if (iter != mapS.end())
{
cout << "find the element:" << iter->first << endl;
cout << "delete element:" << iter->first << endl;
cout << "=================================" << endl;
mapS.erase(iter);
}
else
cout << "not find the element" << endl;
for(iter=mapS.begin();iter!=mapS.end();iter)
{
cout << "| " << iter->first << " | " << iter->
second << " |" << endl;
}
cout << "=================================" << endl;
return 0;
}
Problem Description
夏天来了~~好开心啊,呵呵,好多好多水果~~
Joe经营着一个不大的水果店.他认为生存之道就是经营最受顾客欢迎的水果.现在他想要一份水果销售情况的明细表,这样Joe就可以很容易掌握所有水果的销售情况了.
Input
第一行正整数N(0<N<=10)表示有N组测试数据.
每组测试数据的第一行是一个整数M(0<M<=100),表示工有M次成功的交易.其后有M行数据,每行表示一次交易,由水果名称(小写字母组成,长度不超过80),水果产地(小写字母组成,长度不超过80)和交易的水果数目(正整数,不超过100)组成.
Output
对于每一组测试数据,请你输出一份排版格式正确(请分析样本输出)的水果销售情况明细表.这份明细表包括所有水果的产地,名称和销售数目的信息.水果先按产地分类,产地按字母顺序排列;同一产地的水果按照名称排序,名称按字母顺序排序.
两组测试数据之间有一个空行.最后一组测试数据之后没有空行.
Sample Input:
1
5
apple shandong 3
pineapple guangdong 1
sugarcane guangdong 1
pineapple guangdong 3
pineapple guangdong 1
Sample Output:
guangdong
|----pineapple(5)
|----sugarcane(1)
shandong
|----apple(3)
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
typedef map<string,int> Maptype; //string表示水果名字
//int表示水果的数目(初始化时自动设置为0)
int main()
{
for(int N;cin>>N;) //有N组测试数据
for(int M,L=0;N&&cin>>M;--N)
{
cout<<(L++?"\n":""); //空行技术
map<string,Maptype> Map; //string表示水果的产地
int num;
string name,place;
while(M--) //有M次交易
{
cin>>name>>place>>num;
Map[place][name]+=num;
}
map<string,Maptype>::iterator iter;
for(iter=Map.begin();iter!=Map.end();++iter)
{
cout<<iter->first<<endl; //因为map类型不能使用sort()等排序函数
//因此默认按key数值(而不是输入的先后顺序)排序
map<string,int>::iterator it;
for(it=iter->second.begin();it!=iter->second.end();++it)
cout<<" |----"<<it->first<<"("<<it->second<<")"<<endl;
}
}
return 0;
}