map是一种STL库中提供的数据存储结构,其内部实现可以自行百度。由于map是一个非线程安全的存储结构,因此必须在使用的时候加入线程锁的功能(多线程必加,否则当出现多个线程对同一个Map进行读写时导致的内存不同步)。
1.map是使用键与键值进行比配,并且两者具有一一对应的关系。(键简称key,键值简称value)
2.map的用法:map<键的类型,键值的类型> 变量名;
3.定义map示例:
一个简单的例子:一对一
map student_map; //学生的学号和名字
使用方法:
student_map["guozh"] = 2015211; //在student_map中产生了"guozh"其对应的键值(学号)为2015211
那么除了上面这个方法还可以怎么添加到map容器当中呢?对,调用map自带的操作函数(xxx为图本身)
xxx.insert(pair<键,键值>(键变量,键值变量));
//例子
map test_map;
//插入一个key=3,value=4
test_map.insert(pair(3,4));
那我们怎么知道map里面是不是真的把这个值存进去了呢?调用map自带的函数find(键);
在此之前,我们需要先了解一下map函数里面自带的迭代器。
迭代器详细的定义什么的百度去(可以简单的理解为指针的高级版,特别的在迭代器之中有两个关键成员first和second,
当这个迭代器指向一个具体的map之中某一个具体的键值时,first就为键(key),second就为键值(value))
在使用之前,在这里我们需要先定义一个迭代器(类型必须与要指向的map类型一致)。定义的方法:map<键,键值>::iterator 变量名;
xxx.find(键);
//例子
map test_map;
map::iterator it_check;
//插入一个key=3,value=4
test_map.insert(pair(3,4));
iterator = test_map.find(3);
cout<< iterator->first <<" " <second<
输出结果:
3 4
要存储的结构类型(特别是map
map的效率是否最大化(如下);
使用map来存储结构体时有两种情况,一种是使用结构体作为key,另外一种是结构体作为value。
当结构体作为key时,map函数要求结构对结构体进行重载(体现在:编译器不通过爆出需要重载),这个就没有尝试过。
当结构体作为value时,就当作正常键值使用。可以对结构体作为value做进一步优化:因为当value结构体时,(查找或者遍历时)map内部每次移动都会移动一个结构体的大小(涉及到结构体对齐),而一旦这个结构体很大并且map内部数量大时,就会影响到map的查找效率,因此,存放结构体指针(不管你结构体多大,指针就4个字节)成为了一个最好的优化方法(不考虑用hash_map替换map情况下)定义如下:
typedef struct _PERSONINFO
{
int32_t user_id;
int64_t program_id;
string data;
}PERSONINFO,* P_PERSONINFO;
map person_map;
当然在代码上可能会复杂一点(考虑到擦除map里面的信息时,不能只单单调用一个函数erase()或者clear()去擦除,否则会内存泄漏,还需要遍历map下的每一个键并使用delete 键值,才可以调用函数erase()或者clear()擦除)
用于解决一对多的方法,根据一个用户id对多个节目id有不同的分数,
可以这么定义map嵌套:
map> person_assess_map;
注:第一个int64_t为user_id,第二个int64_t为program_id,第三个int32_t为score,这样理解好像有点违背key和value一一对应的原则,然后实际上还是一个key对应一个value,只不过这个value变成了一个map,这个map里面存放的是program_id(key)以及score(value)举一个嵌套的例子(于上面无关是全新的例子):(完善嵌套的find使用以及遍历方法(均离不开迭代器的使用))
int main (int argc, char **argv)
{
map > multiMap;
map tmp;
map test_map;
map >::iterator multitr;
map::iterator intertr;
tmp[9] = 9;
tmp[10] = 10;
multiMap[10] = tmp; //此处tmp作为value进行赋值是可以的,但是相同类型的map之间不可以直接赋值
multiMap[10][11] = 11;
multiMap[5][30]=30;
multitr = multiMap.find(10);
if(multitr == multiMap.end())
{
cout<< "Not find data";
//cout <first << " " << multitr->second->first << " " multitr->sencond->second;
}
else //嵌套map之中使用find函数去查找
{
cout <first << "\n" ;
intertr = multitr->second.find(10); //此处的second相当于map
if(intertr != multitr->second.end())
{
cout << intertr->first << " " << intertr->second << "\n";
}
}
//嵌套map之中的遍历方法
for(multitr = multiMap.begin();multitr != multiMap.end();multitr++)
{
for(intertr=multitr->second.begin();intertr != multitr->second.end();intertr++)
{
cout<< multitr->first << " " << intertr->first<< "("<second<<")" << endl;
}
}
return 0;
} /* ----- End of main() ----- */
输出结果:
10
10 10
5 30(30)
10 9(9)
10 10(10)
10 11(11)