C++ Primer(第五版)学习笔记_8_标准模板库_map映照容器

C++ Primer(第五版)学习笔记_8_标准模板库_map映照容器

map映照容器的元素数据是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系。

map映照容器的数据结构也是采用红黑树来实现的。

1、map创建、元素插入和遍历访问

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main()
{
    map<string, float> str;
    //插入元素,按键值的由小到大放入红黑树中
    str["Jack"] = 98.5;
    str["Bomi"] = 96.0;
    str["Kate"] = 97.5;

    for(map<string, float>::iterator iter = str.begin(); iter != str.end(); iter++)
        cout << (*iter).first << " : " << (*iter).second << endl;

    return 0;
}

运行结果:

Bomi : 96

Jack : 98.5

Kate : 97.5

2、删除元素和重复插入值:erase()和clear()方法

(1)与set容器一样,map映照容器的erase()删除元素函数,可以删除某个键值上的所有元素。也可以使用clear()方法清空map映照容器。

(2)对于重复插入的值,只取最后插入的值

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main()
{
    map<int, char> str;
    //插入元素,按键值的由小到大放入红黑树中
    str[25] = 'm';
    str[28] = 'k';
    str[10] = 'x';
    str[30] = 'a';
    str[25] = 'i'; //重复插入的值,采用最后插入的值
    str[10] = 'y'; //重复插入的值,采用最后插入的值

    cout << "原始数据:" << endl;
    for(map<int, char>::iterator iter = str.begin(); iter != str.end(); iter++)
        cout << (*iter).first << " : " << (*iter).second << endl;

    //删除键值为0的元素
    int n = str.erase(0);
	cout << "删除元素个数:" << n << endl;

	//删除键值为25的元素
    n = str.erase(25);
	cout << "删除元素个数:" << n << endl;
    cout << "erase()后数据:" << endl;
    for(map<int, char>::iterator iter = str.begin(); iter != str.end(); iter++)
        cout << (*iter).first << " : " << (*iter).second << endl;

    str.clear();
    cout << "clear()后数据:" << endl;
    for(map<int, char>::iterator iter = str.begin(); iter != str.end(); iter++)
        cout << (*iter).first << " : " << (*iter).second << endl;
    return 0;
}

运行结果:

原始数据:

10 : y

25 : i

28 : k

30 : a

删除元素个数:0

删除元素个数:1

erase()后数据:

10 : y

28 : k

30 : a

clear()后数据:

3、元素反向遍历:reverse_iterator

需要rbegin()方法和rend方法指出反向遍历的起始位置和终止位置。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main()
{
    map<int, char> str;
    //插入元素,按键值的由小到大放入红黑树中
    str[25] = 'm';
    str[28] = 'k';
    str[10] = 'x';
    str[30] = 'a';

    for(map<int, char>::reverse_iterator iter = str.rbegin(); iter != str.rend(); iter++)
        cout << (*iter).first << " : " << (*iter).second << endl;
    return 0;
}

运行结果:

30 : a

28 : k

25 : m

10 : y

4、元素的搜索:find()

与set一样,使用find()方法搜索某个键值,搜索到了返回键值所在迭代器位置。否则,返回end()迭代器位置。由于采用红黑树结构,搜索速度是极快的。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main()
{
    map<int, char> str;
    //插入元素,按键值的由小到大放入红黑树中
    str[25] = 'm';
    str[28] = 'k';
    str[10] = 'x';
    str[30] = 'a';

    map<int, char>::iterator iter;
    iter = str.find(28);
    if(iter != str.end())
        cout << (*iter).first << " : " << (*iter).second << endl;
    else
        cout << "not found it" << endl;
    return 0;
}

运行结果:

28 : k

5、自定义比较函数

默认情况下,按照键值由小到大的顺序插入元素。由于内部数据结构都是红黑树,因此编写比较函数与set是一致的。编写方法有两种,

(1)如果元素不是结构体,那么可以编写比较函数。下面实现键值由大道小的顺序将元素插入map中:

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

struct myComp
{
    bool operator()(const int& a, const int& b)
    {
         return a > b;
    }
};

int main()
{
    //插入元素,按键值的由大到小放入红黑树中
    map<int, char, myComp> str;

    str[25] = 'm';
    str[28] = 'k';
    str[10] = 'x';
    str[30] = 'a';

    for(map<int, char, myComp>::iterator iter = str.begin(); iter != str.end(); iter++)
        cout << (*iter).first << " : " << (*iter).second << endl;

    return 0;
}

运行结果:

运行结果:

30 : a

28 : k

25 : m

10 : x

(2)如果元素是结构体,那么,可以直接把比较函数写在结构体里面。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

struct Info
{
    string name;
    float score;
    //必须要写重载函数,重载"<"操作符,自定义排序规则
    bool operator < (Info a) const
    {
        //按score由大到小排列。如果要由小到大排列,使用">"号即可;
        return a.score < score;
    }
};

int main()
{
    //插入元素,按键值的由大到小放入红黑树中
    map<Info, int> str;
    Info info;

    info.name = "Jack";
    info.score = 60;
    str[info] = 25;
    info.name = "Bomi";
    info.score = 80;
    str[info] = 10;
    info.name = "Peti";
    info.score = 66.5;
    str[info] = 30;

    for(map<Info, int>::iterator iter = str.begin(); iter != str.end(); iter++)
    {
        cout << (*iter).second << " : ";
        cout << ((*iter).first).name << " " << ((*iter).first).score << endl;
    }
    return 0;
}

运行结果:

10 : Bomi 80

30 : Peti 66.5

25 : Jack 60

6、字符映照数字的map写法

对数字的各位进行分离,采用取余数的数学操作是很耗时的。而把数字当成字符串,使用map的映照功能,很方便地实现了数字分离。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main()
{
    //插入元素,按键值的由大到小放入红黑树中
    map<char, int> str;
    str['0'] = 0;
    str['1'] = 1;
    str['2'] = 2;
    str['3'] = 3;
    str['4'] = 4;
    str['5'] = 5;
    str['6'] = 6;
    str['7'] = 7;
    str['8'] = 8;
    str['9'] = 9;
    /*
	//上面赋值语句可以用循环代码简化
    for(int j = 0; j < 10; j++)
        m['0' + j] = j;
    */
    string a;
    a = "6234";
    int sum = 0;
    for(int i = 0; i < a.length(); i++)
        sum += str[a[i]];
    cout << "各个数字的和为: " << sum << endl;

    sum = str[a[0]];
    for(int i = 1; i < a.length(); i++)
    {
        sum *= 10;
        sum += str[a[i]];
    }
    cout << "字符串转化为数字: " << sum << endl;
}

运行结果:

各个数字的和为:15

字符串转化为数字:6234

7、数字映照字符的map写法

#include <iostream>
#include <stdio.h>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main()
{
    //插入元素,按键值的由大到小放入红黑树中
    map<int, char> str;
    str[0] = '0';
    str[1] = '1';
    str[2] = '2';
    str[3] = '3';
    str[4] = '4';
    str[5] = '5';
    str[6] = '6';
    str[7] = '7';
    str[8] = '8';
    str[9] = '9';

    /*
    //上面赋值语句可以用循环代码简化
    for(int j = 0; j < 10; j++)
        m[j] = '0' + j;
    */

    int n = 7;
    string single;
    cout << "单位数字转化为字符串: " << single + str[n] << endl;

    int num = 6234;
    string s;
    for(int i = num; i != 0; i /= 10)
    {
        s.insert(s.begin(), str[i % 10]);
    }
    cout << "多位数字转化为字符串: " << s << endl;

    return 0;
}

运行结果:

单位数字转化为字符串:7

多位数字转化为字符串:6234

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 09:06:08

C++ Primer(第五版)学习笔记_8_标准模板库_map映照容器的相关文章

C++ Primer(第五版)学习笔记_6_标准模板库_set集合容器

C++ Primer(第五版)学习笔记_6_标准模板库_set集合容器 Set集合容器实现了红黑树(Red-BlackTree)的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排序,把该元素放到适当的位置. (1)确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值: (2)另外,还得确保根节点左子树的高度与右子树的高度相等.这样,二叉树的高度最小,从而检索速度最快. 平衡二叉检索树的检索使用中序遍历算法,检索效率高.默认情况下,将键值由小到大遍历. 对于s

C++ Primer(第五版)学习笔记_9_标准模板库_multimap多重映照容器

C++ Primer(第五版)学习笔记_9_标准模板库_multimap多重映照容器 多重映照容器multimap与map结构基本相同,但由于重复键值存在,所以multimap的元素插入.删除.查找都与map的方法不相同. 1.multimap对象创建.元素插入 插入元素时,需要使用insert()方法和类似pair<string,double>("Jack", 300.5)的元素结构.可以看到,重复的元素是按照插入的先后顺序排序的. #include <iostre

C++ Primer(第五版)学习笔记_5_标准模板库string(2)

C++ Primer(第五版)学习笔记_5_标准模板库string(2) 10.搜索string对象的元素或子串 采用find()方法可查找字符串中的第一个字符元素(char, 用单引号界定)或者子串(用双引号界定):如果查到,则返回下标值(从0开始计数),如果查不到,则返回一个很大的数string:npos(即:4294967295). #include <iostream> #include <stdio.h> #include <string> using nam

C++ Primer(第五版)学习笔记_3_标准模板库vector(2)

C++ Primer(第五版)学习笔记_3_标准模板库vector(2) 欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢 6.元素的插入 insert()方法可以在vector对象的任意位置前插入一个新的元素,同时,vector自动扩张一个元素空间,插入位置后的所有元素依次向后挪动一个位置. 要注意的是,insert()方法要求插入的位置,是元素的迭代器位置,而不是元素的下标. #include <iostream> #include <vector> using namespa

C++ Primer(第五版)学习笔记_1_标准模板库--快速入门

C++ Primer(第五版)学习笔记_1_标准模板库--快速入门 欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢 标准模板库(STL)提供三种类型的组件:容器.迭代器和算法,他们都支持泛型程序设计标准. 容器主要有两类:顺序容器和关联容器.顺序容器(vector.list.deque和string等)是一系列元素的有序集合.关联容器(set.multiset.map和multimap)包含查找元素的键值. 迭代器的作用是遍历容器. STL算法库包含四类算法:排序算法.不可变序算法.变序性算法

C++ Primer(第五版)学习笔记_2_标准模板库vector(1)

C++ Primer(第五版)学习笔记_2_标准模板库vector(1) 欢迎大家阅读参考,如有错误或疑问请留言纠正,谢谢 向量容器vector不但能像数组一样进行随机访问,还能在尾部插入元素,完全可以替代数组. 值得注意的是,vector具有内存自动管理的功能,对于元素的插入和删除,可以动态调整所占的内存空间. 容器vector的下标是从0开始的,如果vector容器的大小是n,则元素下标为0~n-1,这和数组的一样的.不一样的是,vector可以随时调整其大小. vector重要的方法有三个

C++ Primer(第五版)学习笔记_4_标准模板库string(1)

C++ Primer(第五版)学习笔记_4_标准模板库string(1) 1.创建string对象 创建一个空字符串,其长度为0 #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { string s; cout << s.length() << endl; return 0; } 运行结果: 0 2.给string对象赋值

C++ Primer(第五版)学习笔记_7_标准模板库_multiset多重集合容器

C++ Primer(第五版)学习笔记_7_标准模板库_multiset多重集合容器 多重集合容器multiset与set一样,也是使用红黑树来组织元素数据的,唯一不用的是,multiset允许重复的元素键值插入.其结构示意图如下: 1.multiset元素插入 #include <iostream> #include <stdio.h> #include <vector> #include <set> #include <string> usi

C++ Primer 学习笔记_13_标准模板库_list双向链表容器

C++ Primer 学习笔记_13_标准模板库_list双向链表容器 list容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入.删除和查找都是超快速的.下图是双向循环链表的结构示意图. list的每个节点有三个域:前驱元素指针域.数据域和后继元素指针域.前驱元素指针域保存了前驱元素的首地址:数据域则是本节点的数据:后继元素指针域则保存了后继元素的首地址.list的头结点的前驱元素指针域保存的是链表中尾元素的首地址,而list的尾