C++ map 映射的简单使用

说明:这篇文章仅做为笔记,学习用途,有许多是摘录自看到比较好的文章,在这里不一一叙述引用地方。

一、基本介绍

1.1 map的定义

我们首先要理解键名与键值是什么:

键名:就是存的值的编号

键值:就是要存放的数据

map具体的定义参考http://www.cplusplus.com/reference/map/map/,这里还有比较详细的函数说明可以进行学习了解:

Maps are associative containers that store elements formed by a combination of a key value and a mapped value, following a specific order.

映射是一种关联容器,存储键值和映射值按特定顺序组合而成的元素。

In a map, the key values are generally used to sort and uniquely identify the elements, while the mapped values store the content associated to this key. The types of key and mapped value may differ, and are grouped together in member type value_type, which is a pair type combining both:

typedef pair value_type;

Internally, the elements in a map are always sorted by its key following a specific strict weak ordering criterion indicated by its internal comparison object (of type Compare).
map containers are generally slower than unordered_map containers to access individual elements by their key, but they allow the direct iteration on subsets based on their order.
The mapped values in a map can be accessed directly by their corresponding key using the bracket operator ((operator[]).
Maps are typically implemented as binary search trees.

使用有道翻译的结果:

在一个映射中,键值通常用于排序和惟一地标识元素,而映射的值存储与此键关联的内容。键和映射值的类型可能不同,并在成员类型value_type中组合在一起,value_type是将两者组合在一起的pair类型:

typedef pair value_type;

在内部,映射中的元素总是按照其键进行排序,并遵循由其内部比较对象(类型为Compare)指示的特定严格的弱排序条件。map容器通过键访问单个元素通常比unordered_map容器慢,但是它们允许基于顺序对子集进行直接迭代。映射中的映射值可以通过括号操作符((操作符[])直接访问对应的键。映射通常实现为二叉搜索树。

map容器内部的组织结构图,图片来源:http://c.biancheng.net/view/488.html,有一点需要注意的,键名只能出现一次,不能重复出现:

C++ map 映射的简单使用_第1张图片

这些概念也是网上找找抄抄拼凑的,但是大概理解是个什么东西了,说白了就是用来存储数据的一种实现方法,通过键去找到对应的值,对于数据处理,本质上就是对它进行增删查改。C++中的map容器中常用的一些函数:

  •      begin()         返回指向map头部的迭代器
  •      clear()        删除所有元素
  •      count()         返回指定元素出现的次数
  •      empty()         如果map为空则返回true
  •      end()           返回指向map末尾的迭代器
  •      erase()         删除一个元素
  •      find()          查找一个元素
  •      insert()        插入元素
  •      key_comp()      返回比较元素key的函数
  •      max_size()      返回可以容纳的最大元素个数
  •      rbegin()        返回一个指向map尾部的逆向迭代器
  •      rend()          返回一个指向map头部的逆向迭代器
  •      size()          返回map中元素的个数
  •      swap()           交换两个map
  •      lower_bound()   返回键值>=给定元素的第一个位置
  •      upper_bound()    返回键值>给定元素的第一个位置
  •      value_comp()     返回比较元素value的函数

二、典型应用

2.1 学生的学号与姓名

简单的例子,对学生学号和姓名进行映射,进行增删查改操作:

#include 
#include 
#include 

using namespace std;

int main() {

    map students;//声明 

    //第一种插入方式 
    pair value(1, "aaa");
    students.insert(value);

    //第二种插入方式  
    students.insert(map::value_type(2, "bbb"));
    students.insert(map::value_type(3, "ccc"));

    /************************************查找**********************************/
    //迭代器遍历 
    map::iterator iter1; 
    cout << "迭代器遍历" << endl;
    for (iter1 = students.begin(); iter1 != students.end(); iter1++) {
        //输出first(键)和second(值) 
        cout <first << ' ' << iter1->second << endl;
    }
      
    //反向迭代器遍历 
    map::reverse_iterator iter2;
    cout << "反向迭代器遍历 " << endl;
    for (iter2 = students.rbegin(); iter2 != students.rend(); iter2++) {
        //输出first和second 
        cout <first << ' ' << iter2->second << endl;
    }

    //数组遍历 
    cout << "数组遍历" << endl;
    size_t n = students.size();//map的大小
    for (int i = 1; i <= n; i++) {
        cout << i << " " << students[i] << endl;
    }

    //通过find查找
    iter1 = students.find(2);
    if (iter1 != students.end()) {
        cout << "Find, the value is " << iter1->second << endl;
    }
    else {
        cout << "Do not Find" << endl;
    }
    /**************************************************************************/

    /************************************修改**********************************/
    iter1 = students.find(1);
    //修改值,键名不可修改
    iter1->second = "fff";
    cout << "修改" << endl;
    for (iter2 = students.rbegin(); iter2 != students.rend(); iter2++) {
        //输出first和second 
        cout << iter2->first << ' ' << iter2->second << endl;
    }
    /**************************************************************************/

    /************************************插入**********************************/
    students.insert(map::value_type(4, "ddd"));
    cout << "插入" << endl;
    for (iter2 = students.rbegin(); iter2 != students.rend(); iter2++) {
        //输出first和second 
        cout << iter2->first << ' ' << iter2->second << endl;
    }
    /**************************************************************************/

    /************************************删除************************************/
    students.erase(4);
    cout << "删除" << endl;
    //先查找后删除
    //iter1 = students.find(1);
    //students.erase(iter1);
    //如果删除了会返回1,否则返回0  
    //size_t x = students.erase(1); 

    for (iter2 = students.rbegin(); iter2 != students.rend(); iter2++) {
        //输出first和second 
        cout << iter2->first << ' ' << iter2->second << endl;
    }

    students.clear();
    //students.erase(students.begin(), students.end()); //用迭代器,成片的删除相当于clear  
    if(students.empty()){
        cout << "清空" << endl;
    }
    /**************************************************************************/

    return 0;
}

输出结果:

迭代器遍历
1 aaa
2 bbb
3 ccc
反向迭代器遍历
3 ccc
2 bbb
1 aaa
数组遍历
1 aaa
2 bbb
3 ccc
Find, the value is bbb
修改
3 ccc
2 bbb
1 fff
插入
4 ddd
3 ccc
2 bbb
1 fff
删除
3 ccc
2 bbb
1 fff
清空

在使用map的时候,发现根据键名修改键值使用insert函数是无法进行覆盖的,对C++中map的四种插入方式的比较及同值覆盖问题一文中有详细的解释,使用insert插入的两种方法对map中有这个关键字时数据不覆盖,可使用数组访问的方式进行覆盖。我在上面学生与学号的示例中是使用find函数找到该值,利用second进行修改的,在map中是适用的,因为map容器要求键名是唯一的,而不适用在mutilmap上。

你可能感兴趣的:(C++,c++)