• 【C++笔记】第二十二篇 STL


    C++的STL

    1. STL

    1.1 STL诞生

    ① 长久以来,软件界一直希望建立一种可重复利用的东西。

    ② C++的面向对象和泛型编程思想,目的就是复用性的提升。

    ③ 大多数情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作。

    ④ 为了建立数据结构和算法的一套标准,诞生了STL。

    1.2 STL基本概念

    ① STL(Standard Template Library,标准模板库)

    ② STL 从广义上分为:容器(container)、算法(algorithm)、迭代器(iterator)

    ③ 容器和算法之间通过迭代器进行无缝连接。

    ④ STL 几乎所有的代码都采用了模板类或者模板函数。

    1.3 STL六大组件

    ① STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配准器。

    1. 容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
    2. 算法:各种常用的算法,如sort、find、copy、for_each等。
    3. 迭代器:扮演了容器与算法之间的胶合剂。
    4. 仿函数:行为类似函数,可作为算法的某种策略。
    5. 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
    6. 空间配置器:负责空间的配置与管理。

    1.4 STL容器

    ① 容器:置物之所也。

    ② STL容器就是将运用最广泛的一些数据结构实现出来。

    ③ 常用的数据结构:数组、链表、树、栈、队列、集合、映射表 等。

    ④ 这些容器分为序列式容器和关联式容器两种:

    1. 序列式容器:强调值的排序,序列式容器中每个元素均有固定的位置(怎么往里放,位置就固定了)。
    2. 关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系(不是怎么往里放就怎么排序,它会自动进行排序,然后固定位置)。

    1.5 STL算法

    ① 算法:问题之解法

    ② 有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫算法(Algorithms)

    ③ 算法分为:质变算法和非质变算法。

    1. 质变算法:是指运算过程中会更改区间内的元素内容,例如拷贝、替换、删除等等。
    2. 非质变算法:是指运算过程中不会更改区间内的元素,例如查找、计数、遍历、寻找极值等等。

    1.6 STL迭代器

    ① 迭代器:容器和算法之间粘合剂。

    ② 提供一种方法,使之能够依序寻找某个容器所含的各个元素,而无需暴露容器的内部表示方式。

    ③ 每个容器都有自己专属的迭代器。

    ④ 迭代器使用非常类似于指针,可以先理解迭代器为指针。
    在这里插入图片描述

    1.7 STLvector存放内置数据类型

    ① STL中最常用的容器为Vector,可以理解为数组。

    #include 
    using namespace std;
    #include //STL中每个容器要使用,都要包含对应的头文件
    #include //这是标准算法的头文件
    
    //vector容器存放内置数据类型
    
    void myPrint(int val)
    {
        cout << val << endl;
    }
    
    void test01()
    {
        //创建一个vector容器,数组
        vector<int> v;  //容器中的数据类型为int
    
        //向容器中插入数据
        v.push_back(10);
        v.push_back(20);
        v.push_back(30);
        v.push_back(40);
    
        //通过迭代器访问容器中的数据
        vector<int>::iterator itBegin = v.begin();  //起始迭代器itBegin  指向容器中第一个元素的位置
        vector<int>::iterator itEnd = v.end();  // 结束迭代器itEnd 指向容器中最后一个元素的下一个位置
    
        //第一种遍历方式
        while (itBegin != itEnd)
        {
            cout << *itBegin << endl;  //类似指针,解引用,取出值
            itBegin++; //往后偏移
        }
    
        //第二种遍历方式
        for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << *it << endl;
        }
    
        //第三种遍历方式,利用STL提供遍历算法
        for_each(v.begin(), v.end(), myPrint); //要用STL中的标准算法,就要提供标准算法的头文件
    
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
    - 10  
    - 20  
    - 30  
    - 40  
    - 10  
    - 20  
    - 30  
    - 40  
    - 10  
    - 20  
    - 30  
    - 40  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    1.8 STL存放自定义数据类型

    #include 
    using namespace std;
    #include
    #include //STL中每个容器要使用,都要包含对应的头文件
    
    //vector容器中存放自定义数据类型
    class Person
    {
    public:
        Person(string name, int age)
        {
            this->m_Name = name;
            this->m_Age = age;
        }
        string m_Name;
        int m_Age;
    };
    
    void test01()
    {
        vector<Person>v; //容器中放的是Person的数据类型
    
        Person p1("aaa", 10);
        Person p2("bbb", 20);
        Person p3("ccc", 30);
        Person p4("ddd", 40);
        Person p5("eee", 50);
    
        //向容器中添加数据
        v.push_back(p1);
        v.push_back(p2);
        v.push_back(p3);
        v.push_back(p4);
        v.push_back(p5);
    
        //遍历容器中的数据
        for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl; //<>是什么类型,*it就是什么类型
                                                                                  //第二种拿到属性的方法,由于已知it是个指针,所以也可以通过it->m_Name拿到属性
            cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
        }
    }
    
    //存放自定义数据类型 指针
    void test02()
    {
        vector<Person*>v;
    
        Person p1("aaa", 10);
        Person p2("bbb", 20);
        Person p3("ccc", 30);
        Person p4("ddd", 40);
        Person p5("eee", 50);
    
        //向容器中添加数据
        v.push_back(&p1);
        v.push_back(&p2);
        v.push_back(&p3);
        v.push_back(&p4);
        v.push_back(&p5);
    
        //遍历容器
        for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << "姓名:" << (*it)->m_Name << " 年龄:" << (*it)->m_Age << endl;
        }
    }
    
    int main()
    {
        test01();
        test02();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 姓名:aaa 年龄:10  
    - 姓名:aaa 年龄:10  
    - 姓名:bbb 年龄:20  
    - 姓名:bbb 年龄:20  
    - 姓名:ccc 年龄:30  
    - 姓名:ccc 年龄:30  
    - 姓名:ddd 年龄:40  
    - 姓名:ddd 年龄:40  
    - 姓名:eee 年龄:50  
    - 姓名:eee 年龄:50  
    - 姓名:aaa 年龄:10  
    - 姓名:bbb 年龄:20  
    - 姓名:ccc 年龄:30  
    - 姓名:ddd 年龄:40  
    - 姓名:eee 年龄:50  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    1.9 STL容器嵌套容器

    #include 
    using namespace std;
    #include 
    
    //容器嵌套容器
    
    void test01()
    {
        vector<vector<int>>v; 
    
        //创建小容器
        vector<int>v1;
        vector<int>v2;
        vector<int>v3;
        vector<int>v4;
    
    
        //向4个小容器中添加数据
        for (int i = 0; i < 4; i++)
        {
            v1.push_back(i + 1);
            v2.push_back(i + 2);
            v3.push_back(i + 3);
            v4.push_back(i + 4);
    
        }
    
        //将小容器插入到大容器中
        v.push_back(v1);
        v.push_back(v2);
        v.push_back(v3);
        v.push_back(v4);
    
        //通过大容器,把所有数据遍历一遍
        for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++)
        {
            //(*it)  是一个容器  vector
            for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
            {
                cout << *vit << " ";
            }
            cout << endl;
        }
    
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 1 2 3 4  
    - 2 3 4 5  
    - 3 4 5 6  
    - 4 5 6 7  
    请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    2. string容器

    2.1 简介

    ① string是C++风格的字符串,而string本质上是一个类。

    ② string 和 char * 区别:

    1. char * 是一个指针
    2. string 是一个类,类内部封装了 char *,管理这个字符串是一个char型容器。

    ③ string特点:

    1. string类内部封装了很多成员方法。
    2. 例如,查找find,拷贝copy,删除delete,替换replace,插入insert。
    3. string管理char * 所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责。

    2.2 构造函数

    ① string构造函数原型:

    1. string(); // 创建一个空的字符串 例如:string str;
    2. string(const char * s); // 使用字符串s初始化
    3. string(const string & str); // 使用一个string对象初始化另一个string对象
    4. string(int n,char c); //使用n个字符c初始化

    ② string的多种构造方式没有可比性,灵活使用即可。

    #include 
    using namespace std;
    #include 
    
    //string的构造函数
    
    /*
    1. string();   //  创建一个空的字符串 例如:string str;
    2. string(const char* s);    // 使用字符串s初始化
    3. string(const string & str);  // 使用一个string对象初始化另一个string对象
    4. string(int n, char c);  //使用n个字符c初始化
    */
    
    void test01()
    {
        string s1;  //默认构造就是空字符串
        cout << "s1 = " << s1 << endl;
    
        const char* str = "hello world";   //使用字符串s初始化
        string s2(str);
        cout << "s2 = " << s2 << endl;
    
        string s3(s2);
        cout << "s3 = " << s3 << endl;
    
        string s4(10, 'a');
        cout << "s4 = " << s4 << endl;
    
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - s1 =  
    - s2 = hello world  
    - s3 = hello world  
    - s4 = aaaaaaaaaa   
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    2.3 赋值操作

    ① 给string字符串进行赋值。

    ② 赋值的函数原型:

    1. string& operator=(const char* s); //char * 类型字符串赋值给当前的字符串
    2. string& operator=(const strinng &s); //把字符串s赋给当前的字符串
    3. string& operator=(char c); //字符赋值给当前的字符串
    4. string& assign(const char *s); //把字符串s赋给当前的字符串
    5. string& assign(const char *s,int n); //把字符串s的前n个字符赋给当前的字符串
    6. string& assign(const string &s); //把字符串s赋给当前字符串
    7. string& assign(int n, char c); //用n个字符c赋给当前字符串

    ③ string的赋值方式很多,operator=这种方式是比较常用的。

    #include 
    using namespace std;
    #include 
    
    //string赋值操作
    
    /*
    1. string& operator=(const char* s);  //char * 类型字符串赋值给当前的字符串
    2. string& operator=(const string &s); //把字符串s赋给当前的字符串
    3. string& operator=(char c); //字符赋值给当前的字符串
    4. string& assign(const char *s); //把字符串s赋给当前的字符串
    5. string& assign(const char *s,int n); //把字符串s的前n个字符赋给当前的字符串
    6. string& assign(const string &s); //把字符串s赋给当前字符串
    7. string& assign(int n, char c); //用n个字符c赋给当前字符串
    */
    
    void test01()
    {
        string str1;
        str1 = "hello world";  //第一种等号方式
        cout << "str1 = " << str1 << endl;
    
        string str2;
        str2 = str1;   //第二种等号方式
        cout << "str2 = " << str2 << endl;
    
        string str3;
        str3 = 'a';    //第三种等号方式
        cout << "str3 = " << str3 << endl;
    
        string str4;
        str4.assign("hello C++");   //第一种assign方式
        cout << "str4 = " << str4 << endl;
    
        string str5;
        str5.assign("hello C++",5);   //第二种assign方式,取字符串"hello C++"中的前五个字符赋值给str5
        cout << "str5 = " << str5 << endl;
    
        string str6;
        str6.assign(str5);   //第三种assign方式
        cout << "str6 = " << str6 << endl;
    
        string str7;
        str7.assign(10,'w');   //第四种assign方式
        cout << "str7 = " << str7 << endl;
    
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - str1 = hello world  
    - str2 = hello world  
    - str3 = a  
    - str4 = hello C++  
    - str5 = hello  
    - str6 = hello  
    - str7 = wwwwwwwwww  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    2.4 字符串拼接

    ① 实现在字符串末尾拼接字符串。

    ② 函数原型:

    1. string& operator+=(const char* str); //重载+=操作符
    2. string& operator+=(const char c); //重载+=操作符
    3. string& operator+=(const string& str); //重载+=操作符
    4. string& append+=(const char* s); //把字符串s连接到当前字符串结尾
    5. string& append+=(const char* s, int n); //把字符串s的前n个字符连接到当前字符串结尾
    6. string& append+=(const string &s); //同operator+=(const string& str)
    7. string& append+=(const char &s, int pos, int n); //字符串s从pos开始的n个字符连接到字符串结尾
    #include 
    using namespace std;
    #include 
    
    //string赋值操作
    
    /*
    1. string& operator+=(const char* str);  //重载+=操作符
    2. string& operator+=(const char c); //重载+=操作符
    3. string& operator+=(const string& str); //重载+=操作符
    4. string& append+=(const char* s); //把字符串s连接到当前字符串结尾
    5. string& append+=(const char* s, int n); //把字符串s的前n个字符连接到当前字符串结尾
    6. string& append+=(const string &s); //同operator+=(const string& str)
    7. string& append+=(const char &s, int pos, int n); //字符串s从pos开始的n个字符连接到字符串结尾
    */
    
    void test01()
    {
        string str1 = "我";  //字符串初始化
        str1 += "爱玩游戏";
        cout << "str1 = " << str1 << endl;
    
        str1 += ':';   //追加一个字符
        cout << "str1 = " << str1 << endl;
    
        string str2 = " LOL DNF";
        str1 += str2;    //追加字符串
        cout << "str1 = " << str1 << endl;
    
        string str3 = "I";
        str3.append(" love ");
        cout << "str3 = " << str3 << endl;
    
        str3.append("game abcde ",4);  //只把字符串的前4个拼接过去
        cout << "str3 = " << str3 << endl;
    
        str3.append(str2);  
        cout << "str3 = " << str3 << endl;
    
        str3.append(str2,0,4);  //只截取到LoL,参数2表示从哪个位置开始截取,参数3表示截取字符个数
        cout << "str3 = " << str3 << endl;
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - str1 = 我爱玩游戏  
    - str1 = 我爱玩游戏:  
    - str1 = 我爱玩游戏: LOL DNF  
    - str3 = I love  
    - str3 = I love game  
    - str3 = I love game LOL DNF  
    - str3 = I love game LOL DNF LOL  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    2.5 字符串查找和替换

    ① 查找:查找指定字符串是否存在。

    ② 替换:在指定的位置替换字符串。

    ③ 函数原型:

    //查找str第一次出现位置,从pos开始查找

    1. int find(const string& str, int pos = 0) const;

    // 查找s第一次出现位置,从pos开始查找

    1. int find(const char* s, int pos = 0) const;

    //从pos位置查找s的前n个字符第一次位置

    1. int find(const char* s, int pos, int n) const;

    //查找字符c第一次出现位置

    1. int find(const char c, int pos = 0) const;

    //查找str最后一次位置,从pos开始查找

    1. int rfind(const string& str, int pos = npos) const;

    //查找s最后一次出现位置,从pos开始查找

    1. int rfind(const char* s, int pos = npos) const;

    //从pos查找s的前n个字符最后一次位置

    1. int rfind(const char* s, int pos, int n) const;

    //查找字符c最后一次出现位置

    1. int rfind(const char c, int pos = 0) const;

    //替换从pos开始n个字符为字符串str

    1. string& replace(int pos, int n, const string& str) const;

    //替换从pos开始的n个字符为s

    1. string& replace(int pos, int n, const string* s) const;

    ④ find查找是从左往右,rfind从右往左。

    ⑤ find找到字符串后返回查找的第一个字符位置,找不到返回-1。

    ⑥ replace在替换时,要知道从哪个位置起,多少个字符,替换成什么样的字符串。

    #include 
    using namespace std;
    #include 
    
    //string查找和替换
    
    /*
    //查找str第一次出现位置,从pos开始查找
    1. int find(const string& str, int pos = 0) const;
    // 查找s第一次出现位置,从pos开始查找
    2. int find(const char* s, int pos = 0) const;
    //从pos位置查找s的前n个字符第一次位置
    3. int find(const char* s, int pos, int n) const;
    //查找字符c第一次出现位置
    4. int find(const char c, int pos = 0) const;
    //查找str最后一次位置,从pos开始查找
    5. int rfind(const string& str, int pos = npos) const;
     //查找s最后一次出现位置,从pos开始查找
    6. int rfind(const char* s, int pos = npos) const;
     //从pos查找s的前n个字符最后一次位置
    7. int rfind(const char* s, int pos, int n) const;
     //查找字符c最后一次出现位置
    8. int rfind(const char c, int pos = 0) const;
    //替换从pos开始n个字符为字符串str
    9. string& replace(int pos, int n, const string& str) const;
    //替换从pos开始的n个字符为s
    10. string& replace(int pos, int n, const string* s) const;
    */
    
    
    //1、查找
    void test01()
    {
        string str1 = "abcdefgde"; 
        int pos = str1.find("de");  //从零开始索引,返回值为d出现的位置"3",若找不到子字符串,就返回-1
        if (pos == -1)
        {
            cout << "未找到字符串 pos = " << pos << endl;
        }
        else
        {
            cout << "找到字符串 pos = " << pos << endl;
        }
    
        //rfind
        pos = str1.rfind("de");  //rfind是从右往左查找,find是从左往右查找
    
        cout << "pos=" << pos << endl;
    }
    
    void test02()
    {
        string str1 = "abcdefg";
    
        str1.replace(1, 3, "1111");  // 从 "1" 号位置起,"1111"有四个字符,所以变为4个字符替换成 "1111",而不是出现3个字符替换成"111"
    
        cout << "str1= " << str1 << endl;
    }
    
    int main()
    {
        test01();
        test02();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 找到字符串 pos = 3  
    - pos=7  
    - str1= a1111efg  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    2.6 字符串比较

    ① 功能描述:字符串之间比较。

    ② 比较方式:字符串比较是按字符的ASCII码进行对比。

    1. = = = 返回 0
    2. > > > 返回 1
    3. < < < 返回 -1

    ③ 函数原型:

    1. int compare(const string & s) const; //与字符串s比较
    2. int compare(const char * s) const; //与字符串s比较
    #include 
    using namespace std;
    #include 
    
    //字符串比较
    
    
    //1、查找
    void test01()
    {
        string str1 = "hello";
        string str2 = "hello";
    
        //compar常用于比较两个字符串相等或不相等,判断谁大谁小的意义并不是很大
        if (str1.compare(str2) == 0)
        {
            cout << "str1 等于 str2" << endl;
        }
        else if (str1.compare(str2) > 0)
        {
            cout << "str1 大于 str2" << endl;
        }
        else
        {
            cout << "str1 小于 str2" << endl;
        }
    }
    
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - str1 等于 str2  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2.7 字符串存取

    ① string中单个字符存取方式有两种:

    1. char& operator[](int n); //通过[]方式取字符
    2. char& at(int n); //通过at方式取字符
    #include 
    using namespace std;
    #include 
    
    //string 字符存取
    
    void test01()
    {
        string str = "hello";
    
        cout << "str= " << str << endl;
    
        //1、通过[]访问单个字符
        for (int i = 0; i < str.size(); i++)
        {
            cout << str[i] << " "; 
        }
        cout << endl; //换行符
    
        //2、通过at方式访问单个字符
        for (int i = 0; i < str.size(); i++)
        {
            cout << str.at(i) << " ";
        }
        cout << endl;
    
        //修改单个字符
        str[0] = 'x';
        cout << "str= " << str << endl;
    
        str.at(1) = 'x';
        cout << "str= " << str << endl;
    }
    
    int main()
    {
        test01();
        
        system("pause");
    
        return 0;
    }
    运行结果:  
    - str= hello  
    - h e l l o  
    - h e l l o  
    - str= xello  
    - str= xxllo  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    2.8 字符串插入和删除

    ① 功能描述:对string字符串进行插入和删除字符操作。

    ② 函数原型:

    1. string& insert(int pos, const char * s); // 插入字符串
    2. string& insert(int pos, const string& str); //插入字符串
    3. string& insert(int pos, int n, char c); //在指定位置插入n个字符c
    4. string& erase(int pos, int n = npos); //删除从Pos开始的n个字符

    ③ 插入和删除的起始下标都是从0开始。

    #include 
    using namespace std;
    #include 
    
    //字符串 插入和删除
    
    void test01()
    {
        string str = "hello";
    
        //插入
    
        str.insert(1, "111");
        //hello
        cout << "str = " << str << endl;
    
        //删除
        str.erase(1, 3); //从第“1”个位置起,删3个
        cout << "str = " << str << endl;
    }
    
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - str = h111ello  
    - str = hello  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.9 子串获取

    ① 功能描述:从字符串中获取想要的子串。

    ② 函数原型:

    1. string substr(int pos = 0, int n = npos) const; //返回由pos开始的n个字组成的字符串。

    ③ 灵活的运用求子串功能,可以在实际开发中获取有效的信息。

    #include 
    using namespace std;
    #include 
    
    //string 求子串
    
    void test01()
    {
        string str = "abcdef";
    
        string subStr = str.substr(1, 3); 
    
        cout << "subStr = " << subStr << endl;
    }
    
    //实用操作
    void test02()
    {
        string email = "zhangsan@sina.com";
    
        //从邮件地址中 获取 用户名称
    
        int pos = email.find("@");
        cout << pos << endl;
    
        string usrName = email.substr(0, pos);
        cout << usrName << endl;
    }
    
    int main()
    {
        test01();
        test02();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - subStr = bcd  
    - 8  
    - zhangsan  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    3.vector容器

    3.1 简介

    ① vector数据结构和数组非常相似,也称为单端数组。

    ② vector与普通数组区别:不同之处在于数组是静态空间,而vector可以动态扩展。

    ③ 动态扩展并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间。

    ④ vector容器的迭代器是支持随机访问的迭代器。
    在这里插入图片描述

    3.2 构造函数

    ① 功能描述:创建vector容器

    ② 函数原型:

    1. vector v;
    2. vector(v.begin(), v,end()); //将v[begin().end())区间(前闭后开)中的元素拷贝给本身。
    3. vector(n, elem); //构造函数将n个elem拷贝给本身
    4. vector(const vector &vec); //拷贝构造函数
    #include 
    using namespace std;
    #include 
    
    void printVector(vector<int>&v)   //各种容器的接口,v1容器传进去,就打印v1容器
    {
        for (vector<int>::iterator it = v.begin(); it != v.end();it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    //vector容器构造
    void test01()
    {
        vector<int> v1; //默认构造  无参构造
    
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
    
        printVector(v1);
    
        //通过区间方式进行构造
        vector<int>v2(v1.begin(), v1.end()); //把v1.begin()-v1.end()区间内数给v2
    
        printVector(v2);
    
        //n个elem方式构造
    
        vector<int>v3(10, 100); //这是10个100,不是100个10
    
        printVector(v3);
    
        //拷贝构造
        vector<int>v4(v3);
    
        printVector(v4);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 0 1 2 3 4 5 6 7 8 9  
    - 0 1 2 3 4 5 6 7 8 9  
    - 100 100 100 100 100 100 100 100 100 100  
    - 100 100 100 100 100 100 100 100 100 100  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    3.3 赋值操作

    ① 功能描述:给vector容器进行赋值。

    ② 函数原型:

    1. vector& operator=(const vector &vec); //重载等号操作符。
    2. assign(beg,end); //将[beg,end)区间中的数据拷贝赋值给本身。
    3. assign(n,elem); //将n个elem拷贝赋值给本身。

    ③ vector赋值方式比较简单,使用operator=,或者assign都可以。

    #include 
    using namespace std;
    #include 
    
    //vector赋值
    
    void printVector(vector<int>& v)
    {
        for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << *it << "";
        }
        cout << endl;
    }
    
    void test01()
    {
        vector<int>v1;
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
        printVector(v1);
    
        //赋值 operator=
        vector<int>v2;
        v2 = v1;
        printVector(v2);
    
        //assign
        vector<int>v3;
        v3.assign(v1.begin(), v1.end());  //提供两个迭代器,两个迭代器区间中的元素都赋值给vector容器,区间为前闭后开
        printVector(v3);
    
        //n个elem方式赋值
        vector<int>v4;
        v4.assign(10, 100);
        printVector(v4);
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 0123456789  
    - 0123456789  
    - 0123456789  
    - 100100100100100100100100100100  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    3.4 容量和大小

    ① 功能描述:对vector容器的容量和大小操作。

    ② 函数原型:

    //判断容器是否为空

    1. empy();

    //容器的容量

    1. capacity();

    //返回容器中元素的个数

    1. size();

    //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

    1. resize(int num);

    //重新指定容器的长度为num,若容器变成,则以elem值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

    1. resize(int num, elem);

    ③ vector 容器的容量(用 capacity 表示),指的是在不分配更多内存的情况下,容器可以保存的最多元素个数;而 vector 容器的大小(用 size 表示),指的是它实际所包含的元素个数。

    ④ vector 容器的大小不能超出它的容量,在大小等于容量的基础上,只要增加一个元素,就必须分配更多的内存。注意,这里的“更多”并不是 1 个。换句话说,当 vector 容器的大小和容量相等时,如果再向其添加(或者插入)一个元素,vector 往往会申请多个存储空间,而不仅仅只申请 1 个。

    ⑤ 一旦 vector 容器的内存被重新分配,则和 vector 容器中元素相关的所有引用、指针以及迭代器,都可能会失效,最稳妥的方法就是重新生成。

    #include 
    using namespace std;
    #include 
    
    //vector容器的容量和大小操作
    
    void printVector(vector<int>&v)
    {
        for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << *it << "";
        }
        cout << endl;
    }
    
    void test01()
    {
        vector<int>v1;
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
        printVector(v1);
    
        if (v1.empty()) //为真 代表容器为空
        {
            cout << "v1为空" << endl;
        }
        else
        {
            cout << "v1不为空:" << endl;
            cout << "capacity容量:" << v1.capacity() <<endl;
            cout << "v1的大小为:" << v1.size() << endl;
    
            //重新指定大小
            v1.resize(15);  //如果重新指定的比原来长了,默认用0填充新的位置
            printVector(v1);
    
            v1.resize(20,100);  //利用重载版本,参数2可以指定默认填充值
            printVector(v1);
    
            v1.resize(5);  //如果重新指定的比原来短了,超出的部分会删除掉
            printVector(v1);
        }
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 0123456789  
    - v1不为空:  
    - capacity容量:13  
    - v1的大小为:10  
    - 012345678900000  
    - 012345678900000100100100100100  
    - 01234  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    3.5 插入删除

    ① 功能描述:对vector容器进行插入、删除操作。

    ② 函数原型:

    1. push_back(ele); //尾部插入元素ele
    2. pop__back(); //删除最后一个元素
    3. insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele
    4. insert(const_iterator pos, int count ele); //迭代器指向位置pos插入count个元素
    5. erase(const_iterator pos); //删除迭代器指向的元素
    6. erase(cons_titerator start, const_iterator end); //删除迭代器从start到end之间的元素
    7. clear(); //删除容器中所有元素
    #include 
    using namespace std;
    #include 
    
    void printVector(vector<int>v)
    {
        for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    
    }
    
    void test01()
    {
        vector<int>v1;
        //尾插
        v1.push_back(10);
        v1.push_back(20);
        v1.push_back(30);
        v1.push_back(40);
        v1.push_back(50);
    
        //遍历
        printVector(v1);
    
        //尾删
        v1.pop_back();
        printVector(v1);
    
        //插入 参数是迭代器
        v1.insert(v1.begin(), 100);
        printVector(v1);
    
        //删除  参数也是迭代器
        v1.insert(v1.begin(),2,999);
        printVector(v1);
    
        //删除
        v1.erase(v1.begin());
        printVector(v1);
    
        //清空  方式一:
        v1.erase(v1.begin(), v1.end());
        printVector(v1);
    
        //清空  方式二:
        v1.clear();
        printVector(v1);
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 10 20 30 40 50  
    - 10 20 30 40  
    - 100 10 20 30 40  
    - 999 999 100 10 20 30 40  
    - 999 100 10 20 30 40  
    - 
    -  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    3.6 数据存取

    ① 功能描述:对vector中的数据存取操作。

    ② 函数原型:

    1. at(int idx); ///返回索引idx所指的数据。
    2. operator[]; //返回索引idx所指的数据。
    3. front(); //返回容器中第一个数据元素
    4. back(); //返回容器中最后一个数据元素

    ③ 除了用迭代器获取vector容器中元素,[]和at也可以。

    ④ front返回容器第一个元素。

    ⑤ back返回容器最后一个元素。

    #include 
    using namespace std;
    #include 
    
    void printVector(vector<int>v)
    {
        for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        vector<int>v1;
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
    
        //利用[]方式访问数组中元素
        for (int i = 0; i < v1.size(); i++)
        {
            cout << v1[i] << " ";
        }
        cout << endl;
    
        //利用at方式访问元素
        for (int i = 0; i < v1.size(); i++)
        {
            cout << v1.at(i) << " ";
        }
        cout << endl;
    
        //获取第一个元素
        cout << "第一个元素为:" << v1.front() << endl;
    
        //获取最后一个元素
        cout << "最后一个元素为:" << v1.back() << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 0 1 2 3 4 5 6 7 8 9  
    - 0 1 2 3 4 5 6 7 8 9  
    - 第一个元素为:0  
    - 最后一个元素为:9  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    3.7 互换容器

    ① 功能描述:实现两个容器内元素进行互换。

    ② 函数原型:swao(vec); //将vec与本身的元素互换

    ③ swap可以使两个容器互换,可以达到实用的收缩内存效果。

    #include 
    using namespace std;
    #include 
    
    //vector容器互换
    
    void printVector(vector<int>v)
    {
        for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    
    }
    
    //1、基本使用
    void test01()
    {
        cout << "交换前:" << endl;
    
        vector<int>v1;
        for (int i = 0; i < 10; i++)
        {
            v1.push_back(i);
        }
        
        printVector(v1);
    
        vector<int>v2;
        for (int i = 10; i > 0; i--)
        {
            v2.push_back(i);
        }
        printVector(v2);
    
        cout << "交换后:" << endl;
        v1.swap(v2);
        printVector(v1);
        printVector(v2);
    }
    
    //2、实际用途
    //巧用swap可以收缩内存空间
    void test02()
    {
        vector<int>v;
        for (int i = 0; i < 100000; i++)
        {
            v.push_back(i);
        }
        cout << "v的容量为:" << v.capacity() << endl;
        cout << "v的大小为:" << v.size() << endl;
    
        v.resize(3);  //重新指定大小
        cout << "v的容量为:" << v.capacity() << endl;  //resize操作,容量并没有变,多余的容量浪费了
        cout << "v的大小为:" << v.size() << endl;
    
        //巧用swap收缩内存
        vector<int>(v).swap(v);  //vector(v)创建了一个为匿名对象,会按v的大小初始化这个匿名对象容器的大小
                                 //.swap(v)会对匿名对象容器与原容器做一个交换,则原容器的指针指向匿名对象的容器,匿名对象的容器的指针改为指向原容器
                                 //	系统运行完创建匿名函数这一句语句后对匿名对象的指针(即地址、内存)进行回收
    
        cout << "v的容量为:" << v.capacity() << endl;
        cout << "v的大小为:" << v.size() << endl;
    }
    
    int main()
    {
        test01();
        test02();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 交换前:  
    - 0 1 2 3 4 5 6 7 8 9  
    - 10 9 8 7 6 5 4 3 2 1  
    - 交换后:  
    - 10 9 8 7 6 5 4 3 2 1  
    - 0 1 2 3 4 5 6 7 8 9  
    - v的容量为:138255  
    - v的大小为:100000  
    - v的容量为:138255  
    - v的大小为:3  
    - v的容量为:3  
    - v的大小为:3  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    3.8 预留空间

    ① 功能描述:减少vector在动态扩展容量时的扩展次数。

    ② 函数原型:

    1. reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。
    #include 
    using namespace std;
    #include 
    
    //vector容器 预留空间
    
    void test01()
    {
    
        vector<int>v;
    
        int num = 0;  //统计开辟次数
    
        int* p = NULL; 
    
        for (int i = 0; i < 100000; i++)
        {
            v.push_back(i);
    
            if (p != &v[0])  //一开始指针不指向容量首地址,所以让指针指向容量首地址,开辟内存次数加1
            {
                p = &v[0]; 
                num++;   //由于容量不够,会再次开辟一段容量更大的内存空间,原小容量的内存空间被释放
    
            }
        }
    
        cout << "num:" << num << endl;
    
    }
    
    void test02()
    {
    
        vector<int>v;
    
        //预留空间
        v.reserve(100000);
    
        int num = 0;  //统计开辟次数
    
        int* p = NULL;
    
        for (int i = 0; i < 100000; i++)
        {
            v.push_back(i);
    
            if (p != &v[0])
            {
                p = &v[0];
                num++;
            }
        }
    
        cout << "num:" << num << endl;
    
    }
    
    int main()
    {
        test01();
        test02();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - num:30  
    - num:1  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    4. deque容器

    4.1 简介

    ① 功能:双端数组,可以对头端进行插入删除操作,也可以对尾端进行插入和删除操作。

    ② deque与vector区别:

    1. vector对于头部的插入效率低,数据量越大,效率越低,例如头部后有十万个数据,则往头部插入一个数据时,十万个数据都需要往后挪一挪才能在头部插入数据。
    2. deque相对而言,对头部的插入删除速度会比vector快
    3. vector访问元素时的速度会比deque快,这和两者内部实现有关。

    在这里插入图片描述

    ③ deque内部工作原理:

    1. deque内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据。
    2. 中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间。
      在这里插入图片描述

    ④ deque容器的迭代器也是支持随机访问的。

    4.2 构造函数

    ① 功能描述:deque容器构造。

    ② 函数原型:

    1. dequedeqT; //默认构造形式
    2. 构造函数将[beg,end)区间中的元素拷贝给本身。
    3. deque(n,elem); //构造函数将n个elem拷贝给本身
    4. deque(const deque &deq); //拷贝构造函数

    ③ deque荣哪个器和vector容器的构造方式几乎一致,灵活使用即可。

    #include 
    using namespace std;
    #include 
    
    //deque容器 构造函数
    
    void printDeuque(const deque<int>& d) //const 防止进行写操作,只能进行读
    {
        for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
        {
            //*it = 100;   const使得当进行写操作时,会报错,会提示,避免了进行修改操作
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        deque<int>d1; //无参构造函数
    
        for (int i = 0; i < 10; i++)
        {
            d1.push_back(i);
        }
        printDeuque(d1);
    
        //区间的方式构造
        deque<int>d2(d1.begin(),d1.end());
        printDeuque(d2);
    
        //n个值的方式构造
        deque<int>d3(10,100);
        printDeuque(d3);
        
        //拷贝构造
        deque<int>d4(d3);
        printDeuque(d4);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 0 1 2 3 4 5 6 7 8 9  
    - 0 1 2 3 4 5 6 7 8 9  
    - 100 100 100 100 100 100 100 100 100 100  
    - 100 100 100 100 100 100 100 100 100 100  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    4.3 赋值操作

    ① 功能描述:给deque容器进行赋值。

    ② 函数原型:

    1. deque& operator=(const deque &deq); //重载等号操作符
    2. assign(beg, end); //将[beg,end)区间中的数据拷贝赋值给本身。
    3. assign(n,elem); //将n个elem拷贝赋值给本身。

    ③ deque赋值操作与vector相同。

    #include 
    using namespace std;
    #include 
    
    //deque容器 赋值操作
    
    void printDeuque(const deque<int>&d) 
    {
        for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        deque<int>d1; 
    
        for (int i = 0; i < 10; i++)
        {
            d1.push_back(i);
        }
        printDeuque(d1);
    
        //operator= 赋值
        deque<int>d2;
        d2 = d1;
        printDeuque(d2);
    
        //assign 赋值
        deque<int>d3;
        d3.assign(d1.begin(), d1.end());
        printDeuque(d3);
        
        deque<int>d4(10,100);
        printDeuque(d4);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 0 1 2 3 4 5 6 7 8 9  
    - 0 1 2 3 4 5 6 7 8 9  
    - 0 1 2 3 4 5 6 7 8 9  
    - 100 100 100 100 100 100 100 100 100 100  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    4.4 大小操作

    ① 功能描述:对deque容器的大小进行操作。

    ② 函数原型:

    //判断容器是否为空

    deque.empty();

    //返回容器中的元素的个数

    deque.size();

    //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

    deque.resize(num);

    //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

    deque.resize(num,elem);

    #include 
    using namespace std;
    #include 
    
    //deque容器 大小操作
    
    void printDeuque(const deque<int>&d) 
    {
        for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        deque<int>d1; 
    
        for (int i = 0; i < 10; i++)
        {
            d1.push_back(i);
        }
        printDeuque(d1); 
    
        if (d1.empty())
        {
            cout << "d1为空" << endl;
        }
        else
        {
            cout << "d1不为空" << endl;
            cout << "d1的大小为:" << d1.size() << endl;
            //deque容器没有容量概念
        }
        //重新指定大小
        d1.resize(15, 1); //这里指定填充值为1,如果没有第二个参数,默认的填充值为0
        printDeuque(d1);
    
        d1.resize(5);
        printDeuque(d1);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 0 1 2 3 4 5 6 7 8 9  
    - d1不为空  
    - d1的大小为:10  
    - 0 1 2 3 4 5 6 7 8 9 1 1 1 1 1  
    - 0 1 2 3 4  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    4.5 插入和删除

    ① 功能描述:向deque容器中插入和删除数据。

    ② 函数原型:

    两端插入操作:

    1. push_back(elem); //在容器尾部添加一个数据
    2. push_front(elem); //在容器头部插入一个数据
    3. pop_back(); //删除容器最后一个数据
    4. pop_front(); //删除容器第一个数据

    指定位置操作:

    1. insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
    2. insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值
    3. insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值
    4. clear(); //清空容器的所有数据
    5. erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
    6. erase(pos); //删除pos位置的数据,返回下一个数据的位置。
    #include 
    using namespace std;
    #include 
    
    //deque容器 插入和删除
    
    void printDeuque(const deque<int>&d) 
    {
        for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        deque<int>d1; 
        
        //尾插
        d1.push_back(10);
        d1.push_back(20);
    
        //头插
        d1.push_front(100);
        d1.push_front(200);
        
        printDeuque(d1);
    
        //尾删
        d1.pop_back();
        printDeuque(d1);
    
        //头删
        d1.pop_front();
        printDeuque(d1);
    }
    
    void test02()
    {
        deque<int>d2;
        d2.push_back(10);
        d2.push_back(20);
        d2.push_front(100);
        d2.push_front(200);
    
        printDeuque(d2);
    
        d2.insert(d2.begin(), 1000);
        printDeuque(d2);
    
        d2.insert(d2.begin(), 2, 9999);
        printDeuque(d2);
    
        deque<int>d3;
        d3.push_back(1);
        d3.push_back(2);
        d3.push_front(3);
    
        d3.insert(d3.begin(), d2.begin(), d2.end()); //在d3.begin()的位置,插入区间d2.begin()-d2.end()之间的数
        printDeuque(d3);
    
    }
    
    void test03()
    {
        deque<int>d1;
        d1.push_back(10);
        d1.push_back(20);
        d1.push_front(100);
        d1.push_front(200);
    
        //删除
        deque<int>::iterator it = d1.begin();
        it++;
        d1.erase(it); //d1.erase()为删除所有;d1.clear()也为清空容器所有数据
        printDeuque(d1);
    
        //按区间方式删除
        d1.erase(d1.begin(), d1.end());
        printDeuque(d1);
    
    }
    
    int main()
    {
        test01();
        test02();
        test03();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 200 100 10 20  
    - 200 100 10  
    - 100 10  
    - 200 100 10 20  
    - 1000 200 100 10 20  
    - 9999 9999 1000 200 100 10 20  
    - 9999 9999 1000 200 100 10 20 3 1 2  
    - 200 10 20  
    -- 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    4.6 数据存取

    ① 功能描述:对deque中的数据的存取操作。

    ② 函数原型:

    1. at(int idx); //返回索引idx所指的数据
    2. operator[]; //返回索引idx所指的数据
    3. front(); //返回容器中第一个数据元素
    4. back(); //返回容器中最后一个数据元素

    ③ 除了用迭代器获取deque容器中元素,[]和at也可以。

    #include 
    using namespace std;
    #include 
    
    //deque容器 数据存取
    
    void printDeuque(const deque<int>&d) 
    {
        for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        deque<int>d1; 
        
        //尾插
        d1.push_back(10);
        d1.push_back(20);
        d1.push_back(30);
    
        //头插
        d1.push_front(100);
        d1.push_front(200);
        d1.push_front(300);
    
        //通过[]方式访问元素
        //
        for (int i = 0; i < d1.size(); i++)
        {
            cout << d1[i] << " ";
        }
        cout << endl;
        
        //通过at方式访问元素
        for (int i = 0; i < d1.size(); i++)
        {
            cout << d1.at(i) << " ";
        }
        cout << endl;
        
        cout << "第一个元素为:" << d1.front() << endl;
        cout << "最后一个元素为:" << d1.back() << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 300 200 100 10 20 30  
    - 300 200 100 10 20 30  
    - 第一个元素为:300  
    - 最后一个元素为:30  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    4.7 排序

    ① 利用算法实现对deque容器进行排序。

    ② 算法:

    1. sort(iterator beg, iterator end) //对beg和end区间内元素进行排序

    ③ sort算法非常实用,使用时包含头文件algorithm即可。

    #include 
    using namespace std;
    #include 
    #include  //标准算法头文件
    
    //deque容器 排序操作
    
    void printDeuque(const deque<int>&d) 
    {
        for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)  //表示只读迭代器
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        deque<int>d1; 
        
        //尾插
        d1.push_back(10);
        d1.push_back(20);
        d1.push_back(30);
    
        //头插
        d1.push_front(100);
        d1.push_front(200);
        d1.push_front(300);
    
        printDeuque(d1);
    
        //排序  默认排序规则  从小到大 升序
        //对于支持随机访问的迭代器的容器,都可以利用sort算法直接对其进行排序
        //vector容器也可以利用sort进行排序
        sort(d1.begin(), d1.end());
        cout << "排序后:" << endl;
        printDeuque(d1);
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:  
    - 300 200 100 10 20 30  
    - 排序后:  
    - 10 20 30 100 200 300  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    5. stack容器

    5.1 简介

    ① stack是一种先进后出的容器,它只有一个出口。

    ② 栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为。

    ③ 栈中进入数据称为:入栈 push

    ④ 栈中弹出数据称为:出栈 pop
    在这里插入图片描述

    5.2 常用接口

    ① 功能描述:栈容器常用的对外接口。

    ② 构造函数:

    1. stack stk; //stack采用模板类实现,stack对象的默认构造形式
    2. stack(const stack &stk); //拷贝构造函数

    ③ 赋值操作:

    1. stack& operator=(const stack &stk); //重载等号操作符

    ④ 数据存取:

    1. push(elem); //向栈顶添加元素
    2. pop(); //从栈顶移除第一个元素
    3. top(); //返回栈顶元素

    ⑤ 大小操作:

    1. empty(); //判断堆栈是否为空
    2. size(); //返回栈的大小
    #include
    using namespace std;
    #include 
    
    //栈stack容器
    void test01()
    {
        //特点:符合先进后出数据结构
        stack<int>s;
    
        //入栈
        s.push(10);
        s.push(20);
        s.push(30);
        s.push(40);
    
        //只要栈不为空,查看栈顶,并且执行出栈操作
        while (!s.empty())
        {
            //查看栈顶元素
            cout << "栈顶元素为:" << s.size() << endl;
    
            //出栈
            s.pop();
        }
        cout << "栈的大小:" << s.size() << endl;
    }
    
    int main() {
        test01();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:  
    - 栈顶元素为:4  
    - 栈顶元素为:3  
    - 栈顶元素为:2  
    - 栈顶元素为:1  
    - 栈的大小:0  
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    6. queue容器

    6.1 简介

    ① queue是一种先进先出的数据结构,它有两个出口。

    ② 队列容器允许一段新增元素,从另一端移除元素。

    ③ 队列中只有对头和队尾才可以被外界使用,因此队列不运行有遍历行为。

    ④ 队列中进数据称为入队。

    ⑤ 队列中出数据称为出队。

    6.2 常用接口

    ① 功能描述:栈容器常用的对外接口。

    ② 构造函数:

    1. queue que; //queue采用模板类实现,queue对象的默认构造形式
    2. queue(const queue &que); //拷贝构造函数

    ③ 赋值操作:

    1. queue& operator=(const queue &que); //重载等号操作符

    ④ 数据存储:

    1. push(elem); //往队尾添加元素
    2. pop(); //从对头移除第一个元素
    3. back(); //返回最后一个元素
    4. front(); //返回第一个元素

    ⑤ 大小操作:

    1. empty(); //判断堆栈是否为空
    2. size(); //返回栈的大小
    #include
    using namespace std;
    #include 
    #include
    
    //队列 Queue
    class Person
    {
    public:
        Person(string name, int age)
        {
            this->m_Name = name;
            this->m_Age = age;
        }
        string m_Name;
        int m_Age;
    };
    
    void test01()
    {
        //创建队列
        queue<Person>q;
    
        //准备数据
        Person p1("唐僧", 30);
        Person p2("孙悟空", 1000);
        Person p3("猪八戒", 900);
        Person p4("沙僧", 800);
    
        //入队
        q.push(p1);
        q.push(p2);
        q.push(p3);
        q.push(p4);
    
        cout << "队列大小为:" << q.size() << endl;
    
        //判断只要队列不为空,查看对头,查看队尾,出对
        while (!q.empty())
        {
            //查看对头
            cout << "对头元素 -- 姓名:" << q.front().m_Name << " 年龄:" << q.front().m_Age << endl;
            
            //查看队尾
            cout << "队尾元素 -- 姓名:" << q.back().m_Name << " 年龄:" << q.back().m_Age << endl;
    
            //出对
            q.pop();  //出队是出对头元素
    
        }
        cout << "队列大小为:" << q.size() << endl;
    }
    
    int main() 
    {
        test01();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:  
    - 队列大小为:4  
    - 对头元素 -- 姓名:唐僧 年龄:30
    - 队尾元素 -- 姓名:沙僧 年龄:800
    - 对头元素 -- 姓名:孙悟空 年龄:1000
    - 队尾元素 -- 姓名:沙僧 年龄:800
    - 对头元素 -- 姓名:猪八戒 年龄:900
    - 队尾元素 -- 姓名:沙僧 年龄:800
    - 对头元素 -- 姓名:沙僧 年龄:800
    - 队尾元素 -- 姓名:沙僧 年龄:800
    - 队列大小为:0
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    7. list容器

    7.1 简介

    ① 功能:将数据进行链式存储。

    ② 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。

    ③ 链表的组成:链表由一系列结点组成。

    ④ 结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
    在这里插入图片描述

    ⑤ 添加元素,将原指向下一个元素的指针指向新元素即可,新元素指向下一个元素
    在这里插入图片描述

    ⑥ STL中的链表是一个双向循环链表。

    1. 双向:每一个指针既指向下一个结点的元素,也指向上一个结点的元素。
    2. 循环:最后一个结点的指针会指向第一个结点的元素,第一个结点的指针会指向最后一个结点的元素。
      在这里插入图片描述

    ⑦ 由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器。

    1. 它只能通过指针域一个一个前移/后移去找,而不能连续的内存空间,指针加一个数字,就可以找到数据。

    ⑧ list的优点:

    1. 采用动态存储分配,不会造成内存浪费和溢出。
    2. 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量数据。

    ⑨ list的缺点:

    1. 链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大。

    10.list有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector中是不成立的,vector当插入操作会创建一个更大的数据内容,而vector容器的迭代器却指向原有内存,所以原有的vector容器失效了。

    11.STL中list和vector是两个最长被用的容器,各有优缺点。

    7.2 构造函数

    ① 功能描述:创建list容器。

    ② 函数原型:

    1. list lst; //list采用模板类实现对象的默认构造形式
    2. list(beg,end); //构造函数将[beg,end)区间中的元素拷贝给本身。
    3. list(n,elem); //构造函数将n个elem拷贝给本身。
    4. list(const list &lst); //拷贝构造函数。

    ③ list构造方式同其他几个STL容器一样。

    #include
    using namespace std;
    #include 
    
    void printList(const list<int>&L)
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建list容器
        list<int>L1;  //默认构造
    
        //添加数据
        L1.push_back(10);
        L1.push_back(20);
        L1.push_back(30);
        L1.push_back(40);
    
        //遍历容器
        printList(L1);
    
        //区间方式构造
        list<int>L2(L1.begin(), L1.end());
        printList(L2);
    
        //拷贝构造
        list<int>L3(L2);
        printList(L3);
    
        //n个elem
        list<int>L4(10, 1000);
        printList(L4);
        
    }
    
    int main() {
    
        test01();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:
    - 10 20 30 40
    - 10 20 30 40
    - 10 20 30 40
    - 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    7.3 赋值和交换

    ① 功能描述:给list容器进行赋值,以及交换list容器。

    ② 函数原型:

    1. assign(beg,end); //将[beg,end)区间中的数据拷贝赋值给本身。
    2. assign(n,elem); //将n个elem拷贝赋值给本身。
    3. list& operator=(const list &list); //重载等号操作符。
    4. swap(list); //将lst与本身的元素互换。
    #include
    using namespace std;
    #include 
    
    //list容器赋值和交换
    
    void printList(const list<int>&L)
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建list容器
        list<int>L1;  //默认构造
    
        //添加数据
        L1.push_back(10);
        L1.push_back(20);
        L1.push_back(30);
        L1.push_back(40);
    
        //遍历容器
        printList(L1);
    
        list<int>L2;
        L2 = L1;  //operator= 赋值
        printList(L2);
    
        list<int>L3;
        L3.assign(L2.begin(), L2.end());
        printList(L3);
    
        list<int>L4;
        L4.assign(10, 100);
        printList(L4);
    
    }
    
    //交换
    void test02()
    {
        //创建list容器
        list<int>L1;  //默认构造
        
        //添加数据
        L1.push_back(10);
        L1.push_back(20);
        L1.push_back(30);
        L1.push_back(40);
    
        list<int>L2;
        L2.assign(10, 100);
    
        cout << "交换前:" << endl;
        printList(L1);
        printList(L2);
    
        L1.swap(L2);
        cout << "交换后:" << endl;
        printList(L1);
        printList(L2);
    }
    
    int main() {
    
        test01();
        test02();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:
    - 10 20 30 40
    - 10 20 30 40
    - 10 20 30 40
    - 100 100 100 100 100 100 100 100 100 100
    - 交换前:
    - 10 20 30 40
    - 100 100 100 100 100 100 100 100 100 100
    - 交换后:
    - 100 100 100 100 100 100 100 100 100 100
    - 10 20 30 40
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    7.4 大小操作

    ① 功能描述:对list容器的大小进行操作。

    ② 函数原型:

    //返回容器中元素的个数。

    1. size();

    //判断容器是否为空。

    1. empty();

    //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

    1. resize(num);

    //重新指定容器的长度为num,若容器变成,则以elem值填充新位置。

    //如果容器变短,则末尾超出容器长度的元素被删除。

    1. resize(num,elem);
    #include
    using namespace std;
    #include 
    
    //list容器赋值和交换
    
    void printList(const list<int>&L)
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建list容器
        list<int>L1;  //默认构造
    
        //添加数据
        L1.push_back(10);
        L1.push_back(20);
        L1.push_back(30);
        L1.push_back(40);
    
        //遍历容器
        printList(L1);
    
        //判断容器是否为空
        if(L1.empty())
        {
            cout << "L1为空" << endl;
        }
        else
        {
            cout << "L1不为空:" << endl;
            cout << "L1的元素个数为:" << L1.size() << endl;
        }
    
        //重新指定大小
        L1.resize(10,10000);
        printList(L1);
    
        L1.resize(2);
        printList(L1);
    }
    
    int main() {
    
        test01();
        
        system("pause");
    
        return 0;
    
    }
    运行结果:
    - 10 20 30 40
    - L1不为空:
    - L1的元素个数为:4
    - 10 20 30 40 10000 10000 10000 10000 10000 10000
    - 10 20
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    7.5 插入和删除

    ① 功能描述:对list容器进行数据的插入和删除。

    ② 函数原型:

    1. push_back(elem); //在容器尾部加入一个元素。
    2. pop_back(); //删除容器中最后一个元素。
    3. push_front(elem); //在容器开头插入一个元素。
    4. pop_front(); //从哪个容器开头移除第一个元素
    5. insert(pos,elem); //在pos位置插elem元素的拷贝,返回新数据的位置。
    6. insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。
    7. insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值。
    8. clear(); //移除容器的所有数据。
    9. erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
    10. erase(pos); //删除pos位置的数据,返回下一个数据的位置。
    11. remove(elem); //删除容器中所有与elem值匹配的元素。
    #include
    using namespace std;
    #include 
    
    //list容器赋值和交换
    
    void printList(const list<int>&L)
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建list容器
        list<int>L1;  //默认构造
    
        //添加数据
        L1.push_back(10);
        L1.push_back(20);
        L1.push_back(30);
    
        L1.push_front(100);
        L1.push_front(200);
        L1.push_front(300);
    
        //遍历容器
        printList(L1);
    
        //尾删
        L1.pop_back();
        printList(L1);
    
        //头删
        L1.pop_front();
        printList(L1);
    
        //insert插入
        list<int>::iterator it = L1.begin();
        L1.insert(++it, 1000);
        printList(L1);
    
        //删除
        it = L1.begin();
        L1.erase(it);
        printList(L1);
    
        //移除
        L1.push_back(10000);
        L1.push_back(10000);
        L1.push_back(10000);
        L1.push_back(10000);
        printList(L1);
    
        L1.remove(10000);
        printList(L1);
    
        //清空
        L1.clear();
        printList(L1);
    
    }
    
    int main() {
    
        test01();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:
    - 300 200 100 10 20 30
    - 300 200 100 10 20
    - 200 100 10 20
    - 200 1000 100 10 20
    - 1000 100 10 20
    - 1000 100 10 20 10000 10000 10000 10000
    - 1000 100 10 20
    - 
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    7.6 数据存取

    ① 功能描述:对list容器中数据进行存取。

    ② 函数原型:

    1. front(); //返回第一个元素。
    2. back(); //返回最后一个元素。

    ③ list容器不是连续的内存空间,所以不能通过[]、at等方式随机访问。

    #include
    using namespace std;
    #include 
    
    //list容器  数据存取
    
    void printList(const list<int>&L)
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建list容器
        list<int>L1;  //默认构造
    
        //添加数据
        L1.push_back(10);
        L1.push_back(20);
        L1.push_back(30);
        L1.push_back(40);
    
        //L1[0] 不可以用[]访问list容器中的元素
    
        //L1.at(0) 不可以用at方式访问list容器中的元素
    
        //原因是list本质链表,不是用连续线性空间存储数据,迭代器也是不支持随机访问的。
    
        cout << "第一个元素为:" << L1.front() << endl;
    
        cout << "第一个元素为:" << L1.back() << endl;
    
        //验证迭代器是不支持随机访问的
    
        list<int>::iterator it = L1.begin();
    
        it++;  //因为list是双向的,所以支持递增、递减++、--的操作,但是不支持it = it+1;it = it+2;....,即不支持这样的随机访问      
    
    }
    
    int main() {
    
        test01();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:
    - 第一个元素为:10
    - 第一个元素为:40
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    7.7 反转和排序

    ① 功能描述:将容器中的元素反转,以及将容器中的数据进行排序。

    ② 函数原型:

    1. reverse(); //反转链表
    2. sort(); //链表排序
    #include
    using namespace std;
    #include 
    #include
    
    //list容器  反转和排序
    
    void printList(const list<int>&L)
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    bool myCopare(int v1, int v2)
    {
        //降序 就让第一个数 大于第二个数为真
        return v1 > v2;
    
    }
    
    void test01()
    {
        //反转
        list<int>L1;  
    
        //添加数据
        L1.push_back(20);
        L1.push_back(10);
        L1.push_back(50);
        L1.push_back(40);
        L1.push_back(30);
    
        cout << "反转前:" << endl;
        printList(L1);
    
        //反转
        L1.reverse();
        cout << "反转后:" << endl;
        printList(L1);
    
        //排序
        cout << "排序前:" << endl;
        printList(L1);
    
        //所有不支持随机访问迭代器的容器,不可以用标准算法
        //不支持随机访问迭代器的容器,内部会提供对应的一些算法
        //sort(L1.begin(),L1.end());  //报错,这是标准算法,全局函数的sort()
        L1.sort();  //默认排序规则 从小到大 升序
        cout << "排序后:" << endl;
        printList(L1);
    
        L1.sort(myCopare);  //降序排列 这是成员函数的sort()
        cout << "重载排序算法,降序排序后:" << endl;
        printList(L1);
        
    }
    
    
    int main() 
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
    - 反转前:
    - 20 10 50 40 30
    - 反转后:
    - 30 40 50 10 20
    - 排序前:
    - 30 40 50 10 20
    - 排序后:
    - 10 20 30 40 50
    - 重载排序算法,降序排序后:
    - 50 40 30 20 10
    - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    8. set容器

    8.1 简介

    ① set容器中所有元素在插入时自动被排序。

    ② set容器和multiset容器属于关联式容器,底层结构用二叉树实现。

    ③ set容器与multiset容器区别:

    1. set容器不允许容器中有重复的元素。
    2. multiset容器允许容器中有重复的元素。

    8.2 构造和赋值

    ① 功能描述:创建set容器以及赋值。

    ② 构造函数:

    1. set st; //默认构造函数
    2. set(const set &st); //拷贝构造函数

    ③ 赋值函数:

    1. set& operator=(const set &st); //重载等号操作符

    ④ set容器插入数据时用insert。

    ⑤ set容器插入的数据会自动排序。

    #include
    using namespace std;
    #include 
    
    //set容器  构造和赋值
    
    void printset(const set<int>&L)
    {
        for (set<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    bool myCopare(int v1, int v2)
    {
        //降序 就让第一个数 大于第二个数为真
        return v1 > v2;
    
    }
    
    void test01()
    {
        set<int>s1;  
    
        //插入数据  只有insert方式
        s1.insert(10);
        s1.insert(40);
        s1.insert(30);
        s1.insert(20);
        s1.insert(30);
    
        //遍历容器
        //set容器特点:所有元素插入时候自动被排序
        //set容器不允许插入重复值
        printset(s1);
    
        //拷贝构造
        set<int>s2(s1);
        printset(s2);
    
        //赋值
        set<int>s3;
        s3 = s2;
        printset(s3);
    }
    
    
    int main() {
    
        test01();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:
     - 10 20 30 40
     - 10 20 30 40
     - 10 20 30 40
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    8.3 大小和交换

    ① 功能描述:统计set容器大小以及交换set容器。

    ② 函数原型:

    1. size(); //返回容器中元素的数目。
    2. empty(); //判断容器是否为空。
    3. swap(st); //交换两个集合容器
    #include
    using namespace std;
    #include 
    
    //set容器  大小和交换
    
    void printset(const set<int>&L)
    {
        for (set<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    
    //大小
    void test01()
    {
        set<int>s1;  
    
        //插入数据  只有insert方式
        s1.insert(10);
        s1.insert(40);
        s1.insert(30);
        s1.insert(20);
        s1.insert(30);
    
        printset(s1);
    
        //判断是否为空
        if (s1.empty())
        {
            cout << "s1为空" << endl;
        }
        else
        {
            cout << "s1不为空" << endl;
            cout << "s1的大小为:" << s1.size() << endl;
        }
    }
    
    //交换
    void test02()
    {
        set<int>s1;
    
        //插入数据  只有insert方式
        s1.insert(10);
        s1.insert(40);
        s1.insert(30);
        s1.insert(20);
        s1.insert(30);
    
        set<int>s2;
    
        //插入数据  只有insert方式
        s2.insert(100);
        s2.insert(400);
        s2.insert(300);
        s2.insert(200);
        s2.insert(300);
    
        cout << "交换前:" << endl;
        printset(s1);
        printset(s2);
    
        cout << "交换后:" << endl;
        s1.swap(s2);
        printset(s1);
        printset(s2);
    }
    
    int main() {
    
        test01();
        test02();
        system("pause");
    
        return 0;
    
    }
    运行结果:
     - 10 20 30 40
     - s1不为空
     - s1的大小为:4
     - 交换前:
     - 10 20 30 40
     - 100 200 300 400
     - 交换后:
     - 100 200 300 400
     - 10 20 30 40
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    8.4 插入和删除

    ① 功能描述:set容器进行插入数据和删除数据。

    ② 函数原型:

    1. insert(elem); //在容器中插入元素。
    2. clear(); //清除所有元素。
    3. erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
    4. erase(beg,end); //删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
    5. erase(elem); //删除容器中值为elem的元素。
    #include
    using namespace std;
    #include 
    
    //set容器  插入和删除
    
    void printset(const set<int>&L)
    {
        for (set<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        set<int>s1;  
    
        //插入数据  只有insert方式
        s1.insert(20);
        s1.insert(40);
        s1.insert(30);
        s1.insert(10);
        s1.insert(30);
    
        printset(s1);
    
        //删除
        s1.erase(s1.begin());  //删掉的是排序后的第一个元素10
        printset(s1);
    
        //删除函数的重载版本
        s1.erase(30);   //删除30这个元素
        printset(s1);
    
        //清空方式一:
        s1.erase(s1.begin(), s1.end());
        printset(s1);
    
        //清空方式二:
        s1.clear();
        printset(s1);
    }
    
    int main() 
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 10 20 30 40
     - 20 30 40
     - 20 40
     - 
     - 
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    8.5 查找和统计

    ① 功能描述:对set容器进行查找书籍以及统计数据。

    ② 函数原型:

    1. find(key); //查找key是否存在,若存在,返回该键的元素的迭代器,若不存在,返回set.end();
    2. cout(key); //统计key的元素个数。
    #include
    using namespace std;
    #include 
    
    //set容器  查找和统计
    
    void printset(const set<int>&L)
    {
        for (set<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    
    void test01()
    {
        set<int>s1;  
    
        //插入数据  只有insert方式
        s1.insert(20);
        s1.insert(40);
        s1.insert(30);
        s1.insert(10);
        s1.insert(30);
    
        printset(s1);
    
        //查找返回的是一个迭代器
        set<int>::iterator pos = s1.find(30);   
        if (pos != s1.end())
        {
            cout << "找到元素:" << *pos << endl;
        }
        else
        {
            cout << "未找到元素" << endl;
        }
    }
    
    //统计
    void test02()
    {
        set<int>s1;
    
        //插入数据  只有insert方式
        s1.insert(20);
        s1.insert(40);
        s1.insert(30);
        s1.insert(10);
        s1.insert(30);
    
        int num = s1.count(30);
        //对于set而言 统计结果要么是0 要么是1
        cout << "num = " << num << endl;
    }
    
    int main() {
    
        test01();
        test02();
    
        system("pause");
    
        return 0;
    
    }
    运行结果:
     - 10 20 30 40
     - 找到元素:30
     - num = 1
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    8.6 set和multiset区别

    ① set和multiset区别:

    1. set不可以插入重复数据,而multiset可以。
    2. set插入数据的同时会返回插入结果,表示插入是否成功。
    3. mutiset不会检测数据,因此可以插入重复数据。

    ② 如果不允许插入重复数据可以利用set

    ③ 如果需要插入重复数据利用mutiset

    #include
    using namespace std;
    #include 
    
    //set容器 和 mutiset容器 的区别
    
    void printset(const set<int>&L)
    {
        for (set<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    void test01()
    {
        set<int>s1;  
    
        pair<set<int>::iterator, bool> ret = s1.insert(10);  //s.insert(数)返回的是pair类型,第一个数为迭代器,第二个数为布尔类型
        if (ret.second)
        {
            cout << "第一次插入成功" << endl;
        }
        else
        {
            cout << "第一次插入失败" << endl;
        }
        
        ret = s1.insert(10);  //set不允许插入重复的值,当插入重复的值,返回的第二个参数为False,然后不会插入进去
    
        if (ret.second)
        {
            cout << "第二次插入成功" << endl;
        }
        else
        {
            cout << "第二次插入失败" << endl;
        }
    
        multiset<int>ms;
        //运行插入重复值
        ms.insert(10);
        ms.insert(10);
        ms.insert(10);
    
        for (multiset<int>::const_iterator it = ms.begin(); it != ms.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    
    
    int main() 
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 第一次插入成功
     - 第二次插入失败
     - 10 10 10
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    8.7 内置类型指定排序规则

    ① set容器默认排序规则从小到大,利用仿函数,可以改变排序规则。

    #include
    using namespace std;
    #include 
    
    //set容器排序
    
    class MyCompare
    {
    public:
        bool operator()(int v1, int v2)const //第一个()表示重载符号,第二个()为参数列表
        {
            return v1 > v2;
        }
    };
    
    void test01()
    {
        set<int>s1;  //set容器默认从小到大排序
    
        s1.insert(10);
        s1.insert(40);
        s1.insert(50);
        s1.insert(20);
        s1.insert(30);
    
        for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    
        //指定排序规则为从大到小
    
        set<int, MyCompare>s2;  //此时指定set容器的排序规则为MyCompare,MyCompare()
    
        s2.insert(10);
        s2.insert(40);
        s2.insert(50);
        s2.insert(20);
        s2.insert(30);
    
        for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 10 20 30 40 50
     - 50 40 30 20 10
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    8.8 自定义数据类型指定排序规则

    #include
    using namespace std;
    #include 
    
    //set容器排序
    
    class Person
    {
    public:
        Person(string name, int age)
        {
            this->m_Name = name;
            this->m_Age = age;
        }
        string m_Name;
        int m_Age;
    };
    
    class comparePerson //仿函数本质是一个类
    {
    public:
        bool operator()(const Person& p1, const Person& p2)const
        {
            //安装年龄 降序
            return p1.m_Age > p2.m_Age;
        }
    };
    
    void test01()
    {
        //自定义数据类型  都会指定排序规则
        set<Person, comparePerson>s1;
    
        //创建Person对象
        Person p1("刘备", 24);
        Person p2("关羽", 28);
        Person p3("张飞", 25);
        Person p4("赵云", 21);
    
        s1.insert(p1);
        s1.insert(p2);
        s1.insert(p3);
        s1.insert(p4);
    
        for (set<Person, comparePerson>::iterator it = s1.begin(); it != s1.end(); it++)
        {
            cout << "姓名:" << it->m_Name << "年龄:" << it->m_Age << endl;
        }
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 姓名:关羽年龄:28
     - 姓名:张飞年龄:25
     - 姓名:刘备年龄:24
     - 姓名:赵云年龄:21
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    9. map容器

    9.1 简介

    ① map容器中的所有元素都是pair。

    ② pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)。

    ③ 所有元素都会根据元素的键值自动排序。

    ④ map容器和multimap容器属于关联式容器,底层结构是用二叉树实现。

    ⑤ map容器可以根据key值快速找到value值。

    ⑥ map和multimap区别:

    1. map不允许容器中有重复key值元素。
    2. mutimap运行容器中有重复的key值元素。

    9.2 pair对组的创建

    ① 功能描述:成对出现的数据,利用对组可以返回两个数据。

    ② 两种创建方式:

    1. pair p (value1, value2);
    2. pair p = make_pair(value1,value2);

    ② 两种方式都可以创建对组,记住一种即可。

    #include
    using namespace std;
    #include 
    
    //pair对组的创建
    
    void test01()
    {
        //第一种方式
    
        pair<string, int>p("Tom", 20);
    
        cout << "姓名:" << p.first << "年龄:" << p.second << endl;
    
        //第二种方式
    
        pair<string, int>p2 = make_pair("Jerry", 30);
        cout << "姓名:" << p2.first << "年龄:" << p2.second << endl;
    }
    
    int main() 
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 姓名:Tom年龄:20
     - 姓名:Jerry年龄:30
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    9.3 map容器构造和赋值

    ① 功能描述:对map容器进行构造和赋值操作。

    ② 构造函数:

    1. map mp; //map默认构造函数
    2. map(const map &mp); //拷贝构造函数

    ③ 赋值操作:

    1. map& operator=(const map &mp); //重载等号操作符

    ④ map容器中所有元素都是成对出现,插入元素时候需要使用对组。

    #include
    using namespace std;
    #include 
    
    //map容器 构造和赋值
    
    void printMap(map<int, int>& m)
    {
        for (map<int,int>::iterator it = m.begin();it!=m.end();it++)
        {
            cout << "key = " << it->first << " value = " << it->second << endl;
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建map容器
        map<int, int>m;
    
        m.insert(pair<int, int>(1, 10));  //1为key;10为value
        m.insert(pair<int, int>(3, 30));
        m.insert(pair<int, int>(2, 20));
        m.insert(pair<int, int>(4, 40));
    
        printMap(m);
    
        //拷贝构造
        map<int, int>m2(m);
        printMap(m);
    
        //赋值
        map<int, int>m3;
        m3 = m2;
        printMap(m3);
    }
    
    int main() 
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - key = 1 value = 10
     - key = 2 value = 20
     - key = 3 value = 30
     - key = 4 value = 40
     - 
     - key = 1 value = 10
     - key = 2 value = 20
     - key = 3 value = 30
     - key = 4 value = 40
     - 
     - key = 1 value = 10
     - key = 2 value = 20
     - key = 3 value = 30
     - key = 4 value = 40
     - 
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    9.4 map容器大小和交换

    ① 功能描述:统计map容器大小以及交换map容器。

    ② 函数原型:

    1. size(); //返回容器中元素的数目。
    2. empty(); //判断容器是否为空。
    3. swap(st); //交换两个集合容器。
    #include
    using namespace std;
    #include 
    
    void printMap(map<int, int>& m)
    {
        for (map<int,int>::iterator it = m.begin();it!=m.end();it++)
        {
            cout << "key = " << it->first << " value = " << it->second << endl;
        }
        cout << endl;
    }
    
    //大小
    void test01()
    {
        //创建map容器
        map<int, int>m;
    
        m.insert(pair<int, int>(1, 10));  //1为key;10为value
        m.insert(pair<int, int>(3, 30));
        m.insert(pair<int, int>(2, 20));
    
        printMap(m);
    
        if (m.empty())
        {
            cout << "m为空" << endl;
        }
        else
        {
            cout << "m不为空" << endl;
            cout << "m的大小" << m.size() << endl;
        }
    }
    
    //交换
    void test02()
    {
        map<int, int>m1;
    
        m1.insert(pair<int, int>(1, 10));  //1为key;10为value
        m1.insert(pair<int, int>(3, 30));
        m1.insert(pair<int, int>(2, 20));
    
        map<int, int>m2;
    
        m2.insert(pair<int, int>(4, 100));  
        m2.insert(pair<int, int>(5, 300));
        m2.insert(pair<int, int>(6, 200));
    
        cout << "交换前:" << endl;
        printMap(m1);
        printMap(m2);
    
        m1.swap(m2);
        cout << "交换后:" << endl;
        printMap(m1);
        printMap(m2);
    }
    
    int main() 
    {
        test01();
        test02();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - key = 1 value = 10
     - key = 2 value = 20
     - key = 3 value = 30
     - 
     - m不为空
     - m的大小3
     - 交换前:
     - key = 1 value = 10
     - key = 2 value = 20
     - key = 3 value = 30
     - 
     - key = 4 value = 100
     - key = 5 value = 300
     - key = 6 value = 200
     - 
     - 交换后:
     - key = 4 value = 100
     - key = 5 value = 300
     - key = 6 value = 200
     - 
     - key = 1 value = 10
     - key = 2 value = 20
     - key = 3 value = 30
     - 
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    9.5 map容器插入和删除

    ① 功能描述:map容器进行插入数据和删除数据。

    ② 函数原型:

    1. insert(elem); //在容器中插入元素。
    2. clear(); //清除所有元素。
    3. erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
    4. erase(beg,end); //删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
    5. erase(key); //删除容器中值为key的元素。

    ③ map插入方式很多,记住其一即可。

    #include
    using namespace std;
    #include 
    
    void printMap(map<int, int>& m)
    {
        for (map<int,int>::iterator it = m.begin();it!=m.end();it++)
        {
            cout << "key = " << it->first << " value = " << it->second << endl;
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建map容器
        map<int, int>m;
    
        //第一种:
        m.insert(pair<int, int>(1, 10)); 
    
        //第二种:
        m.insert(make_pair(2, 10));
    
        //第三种:
        m.insert(map<int, int>::value_type(3, 30));  //map容器下为"值"为(3,30)
    
        //第四种:
        m[4] = 40;
    
        cout << m[5] << endl;  //由于没有m[5]没有数,它会自动创建出一个value为0的数
        cout << m[4] << endl;  //不建议用[]插入,但是可以利用key访问到value。
    
        printMap(m);
    
        //删除
        m.erase(m.begin());
        printMap(m);
    
        m.erase(3);  //安装key删除
        printMap(m);
    
        //清空方式一
        m.erase(m.begin(),m.end());  
        //清空方式二
        m.clear();
    
        printMap(m);
    }
    
    int main() 
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 0
     - 40
     - key = 1 value = 10
     - key = 2 value = 10
     - key = 3 value = 30
     - key = 4 value = 40
     - key = 5 value = 0
     - 
     - key = 2 value = 10
     - key = 3 value = 30
     - key = 4 value = 40
     - key = 5 value = 0
     - 
     - key = 2 value = 10
     - key = 4 value = 40
     - key = 5 value = 0
     - 
     - 
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    9.6 map容器查找和统计

    ① 对map容器进行查找数据以及统计数据。

    ② 函数原型:

    1. find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
    2. cout(key); //统计key的元素个数。
    #include
    using namespace std;
    #include 
    
    void test01()
    {
        //创建map容器
        map<int, int>m;
    
        m.insert(pair<int,int>(1, 10));
        m.insert(pair<int, int>(3, 30));
        m.insert(pair<int,int>(2, 20));
        m.insert(pair<int, int>(3, 30));
    
        map<int,int>::iterator pos = m.find(3);
        
        if (pos != m.end())
        {
            cout << "查到了元素 key = " << (*pos).first << " value = " << pos->second << endl;
        }
        else
        {
            cout << "未找到元素" << endl;
        }
    
        //统计
        //map不允许插入重复key元素,count统计而言 结果要么是0 要么是1
        //mutimap 的count统计可以大于1
        int num = m.count(3);
        cout << "num = " << num << endl;
    }
    
    int main() 
    {
        test01();
    
        system("pause");
        
        return 0;
    }
    运行结果:
     - 查到了元素 key = 3 value = 30
     - num = 1
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    9.7 map容器排序

    ① map容器默认排序规则为按照key值进行从小到大排序,利用仿函数,可以改变排序规则。

    ② 利用仿函数可以指定map容器的排序规则。

    ③ 对于自定义数据类型,map必须要指定排序规则,同set容器。

    #include
    using namespace std;
    #include 
    
    class MyCompare
    {
    public:
        bool operator()(int v1, int v2)const
        {
            //降序
            return v1 > v2;
        }
    };
    
    void printMap(map<int, int, MyCompare>& m)
    {
        for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
        {
            cout << "key = " << it->first << " value = " << it->second << endl;
        }
        cout << endl;
    }
    
    void test01()
    {
        //创建map容器
        //不是插了之后再排序,而是在创建的时候就排序
        map<int, int, MyCompare>m;
    
        m.insert(make_pair(1, 10));
        m.insert(make_pair(2, 20));
        m.insert(make_pair(3, 30));
        m.insert(make_pair(4, 40));
        m.insert(make_pair(5, 50));
    
        printMap(m);
    }
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - key = 5 value = 50
     - key = 4 value = 40
     - key = 3 value = 30
     - key = 2 value = 20
     - key = 1 value = 10
     - 
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    10. 评委打分

    ① 案例描述:选手ABCDE,10个评委分别对每一名选手打分,去除最高分,去除评委中最低分,取平均分。

    ② 实现步骤:

    1. 创建五名选手,放到vector容器中。
    2. 遍历vector容器,取出来每一个选手,执行for循环,可以把10个评委打分存到deque容器中。
    3. sort算法对deque容器中分数进行排序,去除最高分和最低分。
    4. deque容器遍历一遍,累加总分。
    5. 获取平均分。
    #include 
    using namespace std;
    #include 
    #include
    #include
    #include  //标准算法头文件
    #include
    
    //选手类
    class Person
    {
    public:
        Person(string name, int score)
        {
            this->m_Name = name;
            this->m_Score = score;
        }
    
        string m_Name;  //姓名
        int m_Score;    //平均分
    };
    
    void createPerson(vector<Person>& v)
    {
        string nameSeed = "ABCDE";
        for (int i = 0; i < 5; i++)
        {
            string name = "选手";
            name += nameSeed[i];
    
            int score = 0;
            Person p(name, score);
    
            //将创建的person对象,放入到容器中
            v.push_back(p);
        }
    }
    
    //2、给5名选手打分
    void setScore(vector<Person>& v)
    {
        for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
        {
            //将评委的分数  放入到deque容器中
            deque<int>d;
            for (int i = 0; i < 10; i++)
            {
                int score = rand() % 41 + 60;   // 60~100
                d.push_back(score);
            }
    
            cout << "选手:" << it->m_Name << "打分:" << endl;
            for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++)
            {
                cout << *dit << " ";
            }
            cout << endl;
    
            //排序
            sort(d.begin(), d.end());
    
            //去除最高分和最低分
            d.pop_back();
            d.pop_front();
    
            //取平均分
            int sum = 0;
            for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++)
            {
                sum += *dit; //累加每个评委的分数
            }
    
            int avg = sum / d.size();
    
            //将平均分 赋值给选手身上
            it->m_Score = avg;
        }
    }
    
    void showScore(vector<Person>&v)
    {
        for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << "姓名:" << it->m_Name << "平均分" << it->m_Score << endl;
        }
    }
    
    int main()
    {
        srand((unsigned int)time(NULL));
    
        //1、创建5名选手
        vector<Person>v;  //存放选手容器
        createPerson(v);
    
        //测试
        for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
        {
            cout << "姓名:" << (*it).m_Name << "分数:" << (*it).m_Score << endl;
        }
    
        //2、给5名选手打分
        setScore(v);
    
        //3、显示最后得分
        showScore(v);
    
        system("pause");
    
        return 0;
    }
    运行结果:  
     - 姓名:选手A分数:0  
     - 姓名:选手B分数:0  
     - 姓名:选手C分数:0  
     - 姓名:选手D分数:0  
     - 姓名:选手E分数:0  
     - 选手:选手A打分:  
     - 87 90 93 71 96 67 60 83 64 73  
     - 选手:选手B打分:  
     - 88 72 66 97 62 90 93 95 100 63  
     - 选手:选手C打分:  
     - 63 85 71 63 92 64 89 90 89 98  
     - 选手:选手D打分:  
     - 98 61 62 76 62 74 90 65 85 68  
     - 选手:选手E打分: 
     - 87 67 96 60 75 63 92 76 98 75  
     - 姓名:选手A平均分78  
     - 姓名:选手B平均分83  
     - 姓名:选手C平均分80  
     - 姓名:选手D平均分72  
     - 姓名:选手E平均分78  
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133

    11. 年龄排序

    ① 案例描述:将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高。

    ② 排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序。

    #include
    using namespace std;
    #include 
    #include
    #include
    
    //list容器  排序案例 对于自定义数据类型 做排序
    
    //按照年龄进行升序 如果年龄相同 按照身高进行降序
    
    class Person
    {
    public:
        Person(string name, int age, int height)
        {
            this->m_Name = name;
            this->m_Age = age;
            this->m_Height = height;
        }
        string m_Name; //姓名
        int m_Age;     //年龄
        int m_Height;  //身高
    };
    
    //指定排序规则
    bool comparePerson(Person &p1, Person &p2)
    {
        //按照年龄 升序
        if (p1.m_Age == p2.m_Age)
        {
            //年龄相同 按照身高排序
            return p1.m_Height > p2.m_Height;
        }
        return p1.m_Age < p2.m_Age;
    }
    
    void test01()
    {
        list<Person>L; //创建容器
    
        //准备数据
        Person p1("刘备", 35, 175);
        Person p2("刘备", 45, 180);
        Person p3("刘备", 50, 170);
        Person p4("刘备", 25, 190);
        Person p5("刘备", 35, 160);
        Person p6("刘备", 35, 200);
    
        //插入数据
        L.push_back(p1);
        L.push_back(p2);
        L.push_back(p3);
        L.push_back(p4);
        L.push_back(p5);
        L.push_back(p6);
    
        for (list<Person>::iterator it = L.begin(); it != L.end(); it++)
        {
            cout << "姓名:" << (*it).m_Name << " 年龄:" << it->m_Age << " 身高:" << it->m_Height << endl;
        }
    
        //排序
        cout << "---------------" << endl;
        cout << "排序后:" << endl;
    
        //L.sort(); 报错,自定义数据类型编译器不知道怎么排序
        L.sort(comparePerson);
        for (list<Person>::iterator it = L.begin(); it != L.end(); it++)
        {
            cout << "姓名:" << (*it).m_Name << " 年龄:" << it->m_Age << " 身高:" << it->m_Height << endl;
        }
    }
    
    
    int main()
    {
        test01();
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 姓名:刘备 年龄:35 身高:175
     - 姓名:刘备 年龄:45 身高:180
     - 姓名:刘备 年龄:50 身高:170
     - 姓名:刘备 年龄:25 身高:190
     - 姓名:刘备 年龄:35 身高:160
     - 姓名:刘备 年龄:35 身高:200
     - $ --------------- $
     - 排序后:
     - 姓名:刘备 年龄:25 身高:190
     - 姓名:刘备 年龄:35 身高:200
     - 姓名:刘备 年龄:35 身高:175
     - 姓名:刘备 年龄:35 身高:160
     - 姓名:刘备 年龄:45 身高:180
     - 姓名:刘备 年龄:50 身高:170
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    12. 员工分组

    案例描述:

    1. 公司今天招募了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在那个部门工作。
    2. 员工信息由:姓名 工资。部门为:策划、美术、研发。
    3. 随机给10名员工分配部门和工资。
    4. 通过multimap进行信息的插入。key(部门编号)value(员工)
    5. 分部门显示员工信息。

    实现步骤:

    1. 创建10名员工,放到vector中
    2. 遍历vector容器,取出每个员工,进行随机分组。
    3. 分组后,将员工部门编号为key,具体员工作为value,放入到multimao容器中。
    4. 分部门显示员工信息。
    #include
    using namespace std;
    #include 
    #include 
    #include
    #include
    
    /*
    实现步骤:
    1. 创建10名员工,放到vector中
    2. 遍历vector容器,取出每个员工,进行随机分组。
    3. 分组后,将员工部门编号为key,具体员工作为value,放入到multimao容器中。
    4. 分部门显示员工信息。
    */
    
    #define CEHUA 0
    #define MEISHU 1
    #define YANFA 2
    
    class Worker
    {
    public:
        string m_Name;
        int m_Salary;
    };
    
    void createWorker(vector<Worker>&v)
    {
        string nameSeed = "ABCDEFGHIJ";
        for (int i = 0; i < 10; i++)
        {
            Worker worker;
            worker.m_Name = "员工";
            worker.m_Name += nameSeed[i];
    
            worker.m_Salary = rand() % 10000 + 10000; //10000~19999
            //将员工放入到容器中
            v.push_back(worker);
        }
    }
    
    void setGroup(vector<Worker>&v,multimap<int,Worker>&m)
    {
        for (vector<Worker>::iterator it = v.begin(); it != v.end(); it++)
        {
            //产生随机部门编号
            int depeId = rand() % 3;//0 1 2
            //将员工插入到分组中
            //key代表部门编号,value代表具体员工
            m.insert(make_pair(depeId, *it));
        }
    }
    
    void showWorkerByGourp(multimap<int,Worker>&m)
    {
        
        //0 A B C 1 D E 2 F G
        cout << "策划部门:" << endl;
    
        multimap<int, Worker>::iterator pos = m.find(CEHUA);
        int count = m.count(CEHUA); //统计具体人数
        int index = 0;
        for (; pos != m.end() && index < count; pos++,index++)
        {
            cout << "姓名:" << pos->second.m_Name << "工资:" << pos->second.m_Salary << endl;
        }
    
        cout << "--------" << endl;
        cout << "美术部门:" << endl;
        pos = m.find(MEISHU);
        count = m.count(MEISHU); //统计具体人数
        index = 0;
        for (; pos != m.end() && index < count; pos++, index++)
        {
            cout << "姓名:" << pos->second.m_Name << "工资:" << pos->second.m_Salary << endl;
        }
    
        cout << "--------" << endl;
        cout << "研发部门:" << endl;
        pos = m.find(YANFA);
        count = m.count(YANFA); //统计具体人数
        index = 0;
        for (; pos != m.end() && index < count; pos++, index++)
        {
            cout << "姓名:" << pos->second.m_Name << "工资:" << pos->second.m_Salary << endl;
        }
    }
    
    int main()
    {
        srand((unsigned int)time(NULL));
    
        //1、创建员工
        vector<Worker>vWorker;
        createWorker(vWorker);
    
        //2、员工分组
        //0号、1号、2号代表不同部门
        multimap<int, Worker>mWorker;
        setGroup(vWorker, mWorker);
    
        //3、分组显示员工
        showWorkerByGourp(mWorker);
    
        //测试
        cout << "--------" << endl;
        cout << "测试:" << endl;
        for (vector<Worker>::iterator it = vWorker.begin(); it != vWorker.end(); it++)
        {
            cout << "姓名:" << it->m_Name << " 工资:" << it->m_Salary << endl;
        }
    
        system("pause");
    
        return 0;
    }
    运行结果:
     - 策划部门:
     - 姓名:员工B工资:11578
     -  - 姓名:员工D工资:11655
     - 姓名:员工G工资:16818
     - 姓名:员工J工资:12160
     - $--------$
     - 美术部门:
     - 姓名:员工F工资:12782
     - 姓名:员工H工资:15815
     - $--------$
     - 研发部门:
     - 姓名:员工A工资:16686
     - 姓名:员工C工资:10638
     - 姓名:员工E工资:11730
     - 姓名:员工I工资:17047
     - $--------$
     - 测试:
     - 姓名:员工A 工资:16686
     - 姓名:员工B 工资:11578
     - 姓名:员工C 工资:10638
     - 姓名:员工D 工资:11655
     - 姓名:员工E 工资:11730
     - 姓名:员工F 工资:12782
     - 姓名:员工G 工资:16818
     - 姓名:员工H 工资:15815
     - 姓名:员工I 工资:17047
     - 姓名:员工J 工资:12160
     - 请按任意键继续. . .
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
  • 相关阅读:
    【Unity3D】UI Toolkit元素
    17.Tensor Product Spaces
    【数据结构与算法】栈与队列相关算法的实现
    代码随想录算法训练营第五十八天| LeetCode 583 两个字符串的删除操作、LeetCode 72 编辑距离、编辑距离总结
    数组16—flat() :递归地将数组展平到指定的深度
    Redis+SpringBoot企业版集群实战------【华为云版】
    尚硅谷-Spring Cloud
    rocketmq-dashboard docker部署设置账号密码
    Revit MEP 平面视图中(立管)怎么设置二维表达?
    【贝叶斯分类3】半朴素贝叶斯分类器
  • 原文地址:https://blog.csdn.net/qq_35793394/article/details/127627335