C++STL中map的使用策略(一)

Map是STL的一个关联容器,它提供一对一的数据处理能力。比如有一个姓名的集合{“Tom”,”Jone”,”Mary”},班级集合{1,2},班级与姓名可能存在以下的映射关系:

       class(“Tom”) = 2,class(“Jone”) = 2,class(“Mary”) = 1

       我们称其中的姓名集合为关键字集合(key),班级集合为值集合(value)

       在C++中map的实现在一个<map>头文件中

1.构造一个集合

map<T1,T2>m;//名为m的,从T1类型到T2类型的映射

2.插入元素

#include <map>
#include <string>
using namespace std;
int main() {
    map<string, int> dict;
    dict.insert(pair<string, int>("Tom", 1)); // {"Tom"->1}
    dict.insert(pair<string, int>("Jone", 2)); // {"Tom"->1, "Jone"->2}
    dict.insert(pair<string, int>("Mary", 1)); // {"Tom"->1, "Jone"->2, "Mary"->1}
   dict.insert(pair<string, int>("Tom", 2)); // {"Tom"->1, "Jone"->2, "Mary"->1}
    return 0;
}

       在C++中通过insert()方法向集合中插入一个新的映射,参数是一个pair类型的结构。这个pair是另一个STL模板——元祖。pair<int,char>(1,’a’)定义了一个整数1和字符a的pair。我们向映射中加入新映射对的时候就是通过pair来实现的。如果插入的key之前已经有value,不会用插入的新的value替代原来的value,也就是插入无效,但并不会报错。

       是如果插入语句没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以通过pair来获得是否插入成功,程序如下:

pair<map<int, string>::iterator, bool> insert_pair;
insert_pair = mapStudent.insert(map<int, string>::value_type (1, "student_one"));

       我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map迭代器,如果插入成功的话,insert_pair.second应该是true,否则为false。

       下面给出一个示例代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
        map<int, string> mapStudent;
        pair<map<int, string>::iterator, bool> insert_Pair;
    insert_Pair = mapStudent.insert(pair<int, string>(1, "student_one"));
    if(insert_Pair.second == true)
    {
               cout<<"Insert Successfully"<<endl;
    }
    else
    {
        cout<<"Insert Failure"<<endl;
    }
    insert_Pair = mapStudent.insert(pair<int, string>(1, "student_two"));
    if(insert_Pair.second == true)
    {
        cout<<"Insert Successfully"<<endl;
    }
    else
    {
        cout<<"Insert Failure"<<endl;
    }
    map<int, string>::iterator iter;
    for(insert_Pair.first = mapStudent.begin(); insert_Pair.first != mapStudent.end(); insert_Pair.first++)
        {
     cout<<insert_Pair.first -> first<<" "<<insert_Pair.first -> second<<endl;
        }
}

       那么现在问题来了,如果想要覆盖掉原有的值,应该怎么办呢?用数组的访问方式!

//验证数组形式插入数据的效果
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
    map<int,string> mapStudent;
    mapStudent[3] = "student_one";
    mapStudent[1] = "student_two";
    mapStudent[3] = "student_three";
    map<int, string>::iterator iter;
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
        cout<<iter->first<<' '<<iter->second<<endl;
}

3.访问映射

       C++访问映射和数组一样,直接用“[]“就能访问,比如dict[“Tom”]就可以获取“Tom”的班级了。而这里有一个比较特殊的地方,如果没有对“Tom”做过映射的话,此时你访问dict[“Tom”],系统将会自动为“Tom”生成一个映射,其value为对应类型的默认值。当然有些时候我们不希望系统自动为我们生成映射,这时候我们需要检测“Tom”是否已经有映射了。需要用到count()函数进行判断

#include <map>
#include <string>
#include <stdio.h>
using namespace std;
int main() {
    map<string, int> dict;  // {}
    dict["Tom"] = 1; // {"Tom"->1}
    dict["Jone"] = 2; // {"Tom"->1, "Jone"->2}
    //dict["Mary"] = 1; // {"Tom"->1, "Jone"->2, "Mary"->1}
    if (dict.count("Mary")) {
        printf("Mary is in class %d\n", dict["Mary"]);
    } else {
        printf("Mary has no class");
    }
    return 0;
}

       4. 遍历映射

       可以通过迭代器访问映射中的每对映射,每个迭代器的first值对应key,second对应value

#include <map>
#include <string>
#include <iostream>
using namespace std;
int main() {
    map<string, int> dict;  // {}
    dict["Tom"] = 1; // {"Tom"->1}
    dict["Jone"] = 2; // {"Tom"->1, "Jone"->2}
    dict["Mary"] = 1; // {"Tom"->1, "Jone"->2, "Mary"->1}
    for (map<string, int>::iterator it = dict.begin(); it != dict.end(); ++it) {
        cout << it->first << " is in class " << it->second << endl;
    }
    return 0;
}

       5. 删除元素

       移除map中某个值用erase(),它有三个重载函数,下面的示例详细说明了它的用法

#include <bits/stdc++.h>
using namespace std;
int main()
{
        map<int, string> mapStudent;
    mapStudent.insert(pair<int, string>(1, "student_one"));
    mapStudent.insert(pair<int, string>(2, "student_two"));
    mapStudent.insert(pair<int, string>(3, "student_three"));
    //如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好
    //如果要删除1,用迭代器删除
    map<int, string>::iterator iter;
    iter = mapStudent.find(1);
    mapStudent.erase(iter);
    //如果要删除1,用关键字删除
    int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0
    //用迭代器,成片的删除
    //一下代码把整个map清空
    mapStudent.erase( mapStudent.begin(), mapStudent.end() );
    //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合
    //自个加上遍历代码,打印输出吧
}

       以上只是我列举一些map常用的方法,如果需要更多的功能,可以查看api

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从流域到海域

《笨办法学Python》 第45课手记

《笨办法学Python》 第45课手记 本节课将对象和类以及他们之间的从属关系。 本学期刚开始学数据结构,贴一些相关的概念: 从整个计算机科学的角度来说,对象是...

21390
来自专栏女程序员的日常

STL的使用和背后数据结构

STL(Standard Template Library即,模板库)包括六个部分:容器(containers)、迭代器(iterators)、空间配置器(al...

23710
来自专栏10km的专栏

java:bytes[]转long的三种方式

bytes[] 到数字类型的转换是个经常用到的代码,解决方式也不止一种,最近需要将bytes[]转为long,有机会深入了解了一下,此文做个总结。 java代码...

70370
来自专栏积累沉淀

DOM解析

Dom解析是将xml文件全部载入,组装成一颗dom树,然后通过节点以及节点之间的关系来解析xml文件 根据 DOM,XML 文档中的每个成分都是一个节点。 ...

22190
来自专栏mySoul

设计模式 里氏替换原则

在场景中,三毛需要什么枪支,就直接new 出一个枪支即可,然后其内通过抽象类获取到对象,然后对齐进行修饰

14360
来自专栏everhad

使用通配符和泛型:完成父子类关系的List对象的类型匹配

使用泛型和通配符都可以让一个方法所表示的算法逻辑适应多种类型。 Java中具备继承关系的类A、B(A extends B)它们的集合List<A>和List<...

12300
来自专栏海天一树

小朋友学C++(5):构造函数

构造函数,作用是完成对象的初始化工作。 可类比于:int a = 1;这里是给变量a赋初值。 构造函数是一种特殊的函数,首先构造函数名与类名是完全一致的,其次构...

27670
来自专栏coding

浅析python中的元类类也是对象动态地创建类用type创建类 metaclass属性元类到底有什么用

在python中,一切皆是对象,就连生成对象的类,自身也是一个对象。既然类也是一个对象,那么类也可以被作为参数传递,也可以赋值给其他变量...

17430
来自专栏everhad

使用通配符和泛型:完成父子类关系的List对象的类型匹配

泛型和通配符 使用泛型和通配符都可以让一个方法所表示的算法逻辑适应多种类型。 Java中具备继承关系的类A、B(A extends B)它们的集合List<A...

20870
来自专栏Jerry的SAP技术分享

Java和ABAP中的几种引用类型的分析和比较

Java编程语言中几种不同的引用类型是面试时经常容易被问到的问题:强引用,软引用,弱引用,虚引用。

8930

扫码关注云+社区

领取腾讯云代金券