STL中C++的map学习

前言:

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函数里面自带的迭代器。

迭代器详细的定义什么的百度去(可以简单的理解为指针的高级版,特别的在迭代器之中有两个关键成员firstsecond

当这个迭代器指向一个具体的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内嵌套vector的设计思路,这种思路(解决一对多)需要注意的地方:vector是一种动态容器,因此使用迭代器保存map某一段vector内容时,一定要加锁(不加锁,多线程操作一个vector时会导致顺序紊乱));

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()擦除)

关于map的嵌套问题

用于解决一对多的方法,根据一个用户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)

 

你可能感兴趣的:(C++学习)