• C++从入门到精通 第十四章(STL容器)【上】


     写在前面:

    1. 本系列专栏主要介绍C++的相关知识,思路以下面的参考链接教程为主,大部分笔记也出自该教程,笔者的原创部分主要在示例代码的注释部分。
    2. 除了参考下面的链接教程以外,笔者还参考了其它的一些C++教材(比如计算机二级教材和C语言教材),笔者认为重要的部分大多都会用粗体标注(未被标注出的部分可能全是重点,可根据相关部分的示例代码量和注释量判断,或者根据实际经验判断)。
    3. 如有错漏欢迎指出。

    参考教程:黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili

    一、string容器

    1、string容器概述

    (1)string的本质:string是C++风格的字符串,而string本质上是一个类。

    (2)string和char *的区别:char *是一个指针,而string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。

    (3)string 类内部封装了很多成员方法,例如查找find、拷贝copy、删除delete、替换replace、插入insert。

    (4)string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责。

    2、string类的构造函数

    string();                //创建一个空的字符串(默认构造)

    string(const string& str);   //使用一个string对象初始化另一个string对象(拷贝构造)

    string(int n, char c);       //使用n个字符c初始化string对象

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. string s1; //默认构造
    7. const char * str = "Hello world"; //使用字符串初始化
    8. string s2(str); //这个也可视作拷贝构造
    9. cout << "s2 : " << s2 << endl;
    10. string s3(s2); //拷贝构造
    11. cout << "s2 : " << s2 << endl;
    12. string s4(10, 'a'); //使用n个字符初始化
    13. cout << "s4 : " << s4 << endl;
    14. }
    15. int main() {
    16. test01();
    17. system("pause");
    18. return 0;
    19. }

    3、string类的赋值操作

    string& operator=(const char* s);     //把char*类型字符串赋值给当前的字符串

    string& operator=(const string &s);   //把字符串s赋给当前的字符串

    string& operator=(char c);          //把字符赋值给当前的字符串

    string& assign(const char *s);       //把字符串s赋给当前的字符串

    string& assign(const char *s, int n);  //把字符串s的前n个字符赋给当前的字符串

    string& assign(const string &s);     //把字符串s赋给当前的字符串

    string& assign(int n, char c);        //用n个字符c组成字符串赋给当前的字符串

    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void test01()
    6. {
    7. string str1;
    8. str1 = "Hello world";
    9. cout << "srt1 = " << str1 << endl;
    10. string str2;
    11. str2 = str1;
    12. cout << "srt2 = " << str2 << endl;
    13. string str3;
    14. str3 = 'a';
    15. cout << "srt3 = " << str3 << endl;
    16. string str4;
    17. str4.assign("Hello C++");
    18. cout << "srt4 = " << str4 << endl;
    19. string str5;
    20. str5.assign("Hello C++", 5);
    21. cout << "srt5 = " << str5 << endl;
    22. string str6;
    23. str6.assign(str5);
    24. cout << "srt6 = " << str6 << endl;
    25. string str7;
    26. str7.assign(10, 'w');
    27. cout << "srt7 = " << str7 << endl;
    28. }
    29. int main() {
    30. test01();
    31. system("pause");
    32. return 0;
    33. }

    4、string字符串拼接函数

    string& operator+=(const char* str);  //重载+=操作符

    string& operator+=(const char c);    //重载+=操作符

    string& operator+=(const string& str); //重载+=操作符

    string& append(const char *s);      //把字符串s连接到当前字符串结尾

    string& append(const char *s, int n);  //把字符串s的前n个字符连接到当前字符串结尾

    string& append(const string &s);     //同operator+=(const string& str)

    string& append(const string &s, int pos, int n);//字符串s中从pos开始的n个字符连接到字符串结尾

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. string str1;
    7. str1 = "我";
    8. str1 += "爱玩游戏";
    9. cout << "str1 = " << str1 << endl;
    10. str1 += ':';
    11. cout << "str1 = " << str1 << endl;
    12. string str2 = " LOL DNF";
    13. str1 += str2;
    14. cout << "str1 = " << str1 << endl;
    15. string str3 = "I";
    16. str3.append(" love ");
    17. cout << "str3 = " << str3 << endl;
    18. str3.append("Python abcde", 6);
    19. cout << "str3 = " << str3 << endl;
    20. str3.append(str2);
    21. cout << "str3 = " << str3 << endl;
    22. str3.append(str2, 0, 4); //参数2:从哪个位置开始截取
    23. cout << "str3 = " << str3 << endl;
    24. str3.append(str2, 4, 4); //参数3:截取字符个数
    25. cout << "str3 = " << str3 << endl;
    26. }
    27. int main() {
    28. test01();
    29. system("pause");
    30. return 0;
    31. }

    5、string类的查找和替换函数

    查找指的是查找指定字符串是否存在,替换指的是在指定的位置替换字符串。

    int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找

    int find(const char* s, int pos = 0) const;   //查找s第一次出现位置,从pos开始查找

    int find(const char* s, int pos, int n) const;  //从pos位置查找s的前n个字符第一次位置

    int find(const char c, int pos = 0) const;     //查找字符c第一次出现位置

    int rfind(const string& str, int pos = npos) const; //查找str最后一次位置,从pos开始查找

    int rfind(const char* s, int pos = npos) const;  //查找s最后一次出现位置,从pos开始查找

    int rfind(const char* s, int pos, int n) const;   //从pos查找s的前n个字符最后一次位置

    int rfind(const char c, int pos = 0) const;     //查找字符c最后一次出现位置

    string& replace(int pos, int n, const string& str);  //替换从pos开始n个字符为字符串str

    string& replace(int pos, int n,const char* s);  //替换从pos开始的n个字符为字符串s

    1. #include
    2. #include
    3. using namespace std;
    4. void test01() //查找
    5. {
    6. string str1 = "abcdefgcd"; //该字符串有两个“cd”
    7. int pos = str1.find("cd"); //find从左往右查
    8. if (pos == -1)
    9. {
    10. cout << "未找到字符串" << endl;
    11. }
    12. else
    13. {
    14. cout << "pos = " << pos << endl;
    15. }
    16. pos = str1.find("df");
    17. if (pos == -1)
    18. {
    19. cout << "未找到字符串" << endl;
    20. }
    21. else
    22. {
    23. cout << "pos = " << pos << endl;
    24. }
    25. pos = str1.rfind("cd"); //rfind从右往左查(位置编号还是从左往右算)
    26. cout << "pos = " << pos << endl;
    27. }
    28. void test02() //替换
    29. {
    30. string str1 = "abcdefg";
    31. str1.replace(2, 3, "kkkk"); //从2号位置起的3个字符替换为“kkkk”
    32. cout << "str1 = " << str1 << endl;
    33. }
    34. int main() {
    35. test01();
    36. test02();
    37. system("pause");
    38. return 0;
    39. }

    6、string字符串比较函数

    比较方式:字符串比较是从第一个字符开始,按字符的ASCII码进行对比,只要出现同位置字符ASCII码不同的情况,那么两个字符串就不相等,认为ASCII码较大的一个字符串更大。

    ①比较结果为“=”,返回0。

    ②比较结果为“>”,返回1。

    ③比较结果为“<”,返回-1。

    int compare(const string &s) const;  //与字符串s比较

    int compare(const char *s) const;   //与字符串s比较

    1. #include
    2. #include
    3. using namespace std;
    4. string compare(string &str1,string &str2)
    5. {
    6. if (str1.compare(str2) == 0)
    7. {
    8. return " 等于= ";
    9. }
    10. else if (str1.compare(str2) == 1)
    11. {
    12. return " 大于> ";
    13. }
    14. else if(str1.compare(str2) == -1)
    15. {
    16. return " 小于< ";
    17. }
    18. }
    19. void test01()
    20. {
    21. string str1 = "hello";
    22. string str2 = "hello";
    23. string str3 = "xello";
    24. string str4 = "heklo";
    25. cout << "str1" << compare(str1, str2) << "str2" << endl;
    26. cout << "str1" << compare(str1, str3) << "str3" << endl;
    27. cout << "str1" << compare(str1, str4) << "str4" << endl;
    28. }
    29. int main() {
    30. test01();
    31. system("pause");
    32. return 0;
    33. }

    7、string字符串的字符存取

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

    char& operator[](int n);  //通过[]方式取字符

    char& at(int n);        //通过at方法获取字符

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. string str = "Hello world";
    7. //通过[]访问单个字符
    8. for (int i = 0; i < str.size(); i++)
    9. {
    10. cout << str[i] << " ";
    11. }
    12. cout << endl;
    13. str[0] = 'h';
    14. //通过at方式访问单个字符
    15. for (int i = 0; i < str.size(); i++)
    16. {
    17. cout << str.at(i) << " ";
    18. }
    19. cout << endl;
    20. str.at(0) = 'H';
    21. for (int i = 0; i < str.size(); i++)
    22. {
    23. cout << str.at(i) << " ";
    24. }
    25. cout << endl;
    26. }
    27. int main() {
    28. test01();
    29. system("pause");
    30. return 0;
    31. }

    8、string字符串的字符插入和字符删除

    对string字符串进行插入和删除操作时,要将string字符串视为字符数组,起始的下标都是从0开始算

    string& insert(int pos, const char* s);     //插入字符串

    string& insert(int pos, const string& str);  //插入字符串

    string& insert(int pos, int n, char c);      //在指定位置插入n个字符c

    string& erase(int pos, int n = npos);      //删除从Pos开始的n个字符

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. string str = "Hello";
    7. str.insert(1, "k2k"); //插入
    8. cout << "str = " << str << endl;
    9. str.erase(1, 3); //删除
    10. cout << "str = " << str << endl;
    11. }
    12. int main() {
    13. test01();
    14. system("pause");
    15. return 0;
    16. }

    9、从字符串string获取子串

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

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. string str = "abcdefg";
    7. string subStr = str.substr(1, 3);
    8. cout << "subStr = " << subStr << endl;
    9. }
    10. void test02()
    11. {
    12. string email = "zhangsan@sina.com";
    13. int pos = email.find("@");
    14. string usrName = email.substr(0, pos);
    15. cout << "usrName = " << usrName << endl;
    16. }
    17. int main() {
    18. test01();
    19. test02();
    20. system("pause");
    21. return 0;
    22. }

    二、vector容器

    1、vector的基本概念

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

    (2)vector与普通数组区别:数组是静态空间,而vector可以动态扩展,而动态扩展并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间。

    (3)vector容器的迭代器是支持随机访问的迭代器。

    2、vector的构造函数

    vector v;              //采用模板实现类实现,默认构造函数

    vector(v.begin(), v.end());    //将v[begin(), end())区间中的元素拷贝给本身

    vector(n, elem);           //构造函数将n个elem拷贝给本身

    vector(const vector &vec);  //拷贝构造函数

    1. #include
    2. #include
    3. using namespace std;
    4. void printVector(vector<int> &v)
    5. {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. vector<int> v1; //默认构造(无参构造)
    15. for (int i = 0; i < 10; i++)
    16. {
    17. v1.push_back(i);
    18. }
    19. printVector(v1);
    20. vector<int> v2(v1.begin(), v1.end()); //通过区间方式进行构造
    21. printVector(v2);
    22. vector<int> v3(10, 199); //n个elem方式构造
    23. printVector(v3);
    24. vector<int> v4(v3); //拷贝构造
    25. printVector(v4);
    26. }
    27. int main() {
    28. test01();
    29. system("pause");
    30. return 0;
    31. }

    3、vector的赋值操作

    vector& operator=(const vector &vec); //重载等号操作符

    assign(beg, end);                  //将[beg, end)区间中的数据拷贝赋值给本身

    assign(n, elem);                   //将n个elem拷贝赋值给本身

    1. #include
    2. #include
    3. using namespace std;
    4. void printVector(vector<int> &v)
    5. {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. vector<int> v1;
    15. for (int i = 0; i < 10; i++)
    16. {
    17. v1.push_back(i);
    18. }
    19. printVector(v1);
    20. vector<int>v2;
    21. v2 = v1; //赋值 operator=
    22. printVector(v2);
    23. vector<int>v3;
    24. v3.assign(v1.begin(), v1.end()); //赋值 assign
    25. printVector(v3);
    26. vector<int>v4;
    27. v4.assign(10, 51); //赋值 n个elem方式
    28. printVector(v4);
    29. }
    30. int main() {
    31. test01();
    32. system("pause");
    33. return 0;
    34. }

    4、vector的容量和大小

    empty();       //判断容器是否为空

    capacity();     //容器的容量

    size();         //返回容器中元素的个数

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

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

    resize(int num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置

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

    1. #include
    2. #include
    3. using namespace std;
    4. void printVector(vector<int> &v)
    5. {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. vector<int> v1,v2;
    15. if (v1.empty())
    16. {
    17. cout << "容器v1为空" << endl;
    18. }
    19. cout << endl;
    20. for (int i = 0; i < 10; i++)
    21. {
    22. v1.push_back(i);
    23. }
    24. printVector(v1);
    25. if (v1.empty())
    26. {
    27. cout << "容器v1为空" << endl;
    28. }
    29. else
    30. {
    31. cout << "容器v1不为空" << endl;
    32. cout << "v1的容量为" << v1.capacity() << endl;
    33. cout << "v1的元素个数为" << v1.size() << endl;
    34. }
    35. v1.resize(15);
    36. printVector(v1); //如果重新指定的长度比原来长了,默认用0填充新位置
    37. cout << "v1的容量为" << v1.capacity() << endl;
    38. cout << "v1的元素个数为" << v1.size() << endl;
    39. v2 = v1;
    40. v2.resize(8);
    41. printVector(v2); //如果重新指定的长度比原来短,则超出长度的元素会被删除
    42. v2.resize(12, 10);
    43. printVector(v2); //重新指定容器的长度,若容器变长,则以elem值填充新位置
    44. }
    45. int main() {
    46. test01();
    47. system("pause");
    48. return 0;
    49. }

    5、vector的插入和删除

    push_back(ele);                          //尾部插入元素ele

    pop_back();                             //删除最后一个元素

    insert(const_iterator pos, ele);              //迭代器指向位置pos插入元素ele

    insert(const_iterator pos, int count,ele);      //迭代器指向位置pos插入count个元素ele

    erase(const_iterator pos);                 //删除迭代器指向的元素

    erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素

    clear();                                //删除容器中所有元素

    1. #include
    2. #include
    3. using namespace std;
    4. void printVector(vector<int> &v)
    5. {
    6. int j = 0;
    7. for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    8. {
    9. cout << *it << " ";
    10. j++;
    11. }
    12. if (j == 0)
    13. {
    14. cout << "什么也没有" << endl;
    15. }
    16. cout << endl;
    17. }
    18. void test01()
    19. {
    20. vector<int> v1;
    21. v1.push_back(10); //尾插
    22. v1.push_back(20);
    23. v1.push_back(30);
    24. v1.push_back(40);
    25. v1.push_back(50);
    26. printVector(v1);
    27. v1.pop_back(); //尾删
    28. printVector(v1);
    29. v1.insert(v1.begin(), 100); //插入 第一个参数是迭代器
    30. printVector(v1);
    31. v1.insert(v1.begin(), 2 ,100);
    32. printVector(v1);
    33. v1.erase(v1.begin()); //删除 参数是迭代器
    34. printVector(v1);
    35. v1.erase(v1.begin(), v1.end()); //v1.clear();具有同等作用
    36. printVector(v1);
    37. }
    38. int main() {
    39. test01();
    40. system("pause");
    41. return 0;
    42. }

    6、vector的数据存取

    at(int idx);   //返回索引idx所指的数据

    operator[];  //返回索引idx所指的数据

    front();     //返回容器中第一个数据元素

    back();     //返回容器中最后一个数据元素

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. vector<int> v1;
    7. for (int i = 0; i < 10; i++)
    8. {
    9. v1.push_back(i);
    10. }
    11. //利用[]方式访问数组元素
    12. for (int i = 0; i < v1.size(); i++)
    13. {
    14. cout << v1[i] << " ";
    15. }
    16. cout << endl;
    17. //利用at方式访问元素
    18. for (int i = 0; i < v1.size(); i++)
    19. {
    20. cout << v1.at(i) << " ";
    21. }
    22. cout << endl;
    23. cout << "第一个元素为: " << v1.front() << endl;
    24. cout << "最后一个元素为: " << v1.back() << endl;
    25. }
    26. int main() {
    27. test01();
    28. system("pause");
    29. return 0;
    30. }

    7、vector的互换容器操作

    swap(vec);   //将vec中的元素与调用该函数的对象本身的元素互换

    1. #include
    2. #include
    3. using namespace std;
    4. void printVector(vector<int> &v)
    5. {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. cout << "交换前:" << endl;
    15. vector<int> v1;
    16. for (int i = 0; i < 10; i++)
    17. {
    18. v1.push_back(i * 10);
    19. }
    20. printVector(v1);
    21. vector<int> v2;
    22. for (int i = 9; i > -1; i--)
    23. {
    24. v2.push_back(i * 10);
    25. }
    26. printVector(v2);
    27. cout << "交换后:" << endl;
    28. v1.swap(v2);
    29. printVector(v1);
    30. printVector(v2);
    31. }
    32. void test02() //巧用swap可以收缩内存空间
    33. {
    34. vector<int>v;
    35. for (int i = 0; i < 100000; i++)
    36. {
    37. v.push_back(i);
    38. }
    39. cout << "v的容量为:" << v.capacity() << endl;
    40. cout << "v的大小为:" << v.size() << endl;
    41. v.resize(3); //重新指定大小
    42. cout << "v的容量为:" << v.capacity() << endl; //容量不会变小
    43. cout << "v的大小为:" << v.size() << endl;
    44. vector<int>(v).swap(v); //vector(v)--匿名对象,按照v的元素给它初始化,本行过后匿名对象被销毁
    45. cout << "v的容量为:" << v.capacity() << endl; //容量变小
    46. cout << "v的大小为:" << v.size() << endl;
    47. }
    48. int main() {
    49. test01();
    50. test02();
    51. system("pause");
    52. return 0;
    53. }

    8、vector允许预留空间

    预留空间也就是先在内存划分一片属于vector对象的空间,这部分空间可以不立即使用,这样可以减少vector在动态扩展容量时的扩展次数。

    reserve(int len);   //容器预留len个元素长度,预留位置不初始化,元素不可访问

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. vector<int> v;
    7. v.reserve(100000); //预留空间
    8. int num = 0; //统计开辟内存次数
    9. int *p = NULL;
    10. for (int i = 0; i < 100000; i++)
    11. {
    12. v.push_back(i);
    13. if (p != &v[0])
    14. {
    15. p = &v[0];
    16. num++;
    17. }
    18. }
    19. cout << "num = " << num << endl;
    20. }
    21. int main() {
    22. test01();
    23. system("pause");
    24. return 0;
    25. }

    三、deque容器

    1、deque容器的基本概念

    (1)deque容器是一个双端数组,可以对头端进行插入删除操作。

    (2)deque与vector的区别:

    ①vector在头部插入或删除元素的效率低,数据量越大,效率越低。

    ②deque在头部插入元素或删除元素的速度比vector快。

    ③vector访问元素时的速度会比deque快,这和两者内部实现有关。

    (3)deque内部的工作原理:

    ①deque内部有个中控器维护每段缓冲区中的内容,缓冲区中存放真实数据。

    ②中控器维护的是每个缓冲区的地址,使得使用deque时像是使用一片连续的内存空间。

    (4)deque容器的迭代器也是支持随机访问的。

    2、deque的构造函数

    deque deqT;           //默认构造形式

    deque(beg, end);          //构造函数将[beg, end)区间中的元素拷贝给本身

    deque(n, elem);           //构造函数将n个elem拷贝给本身

    deque(const deque &deq);  //拷贝构造函数

    1. #include
    2. #include
    3. using namespace std;
    4. void printDeque(const deque<int> &d)
    5. {
    6. for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    7. {
    8. //*it = 100; 容器中的数据不可以修改了
    9. cout << *it << " ";
    10. }
    11. cout << endl;
    12. }
    13. void test01()
    14. {
    15. deque<int>d1;
    16. for (int i = 0; i < 10; i++)
    17. {
    18. d1.push_back(i);
    19. }
    20. printDeque(d1);
    21. deque<int>d2(d1.begin(), d1.end());
    22. printDeque(d2);
    23. deque<int>d3(10, 100);
    24. printDeque(d3);
    25. deque<int>d4(d3);
    26. printDeque(d4);
    27. }
    28. int main() {
    29. test01();
    30. system("pause");
    31. return 0;
    32. }

    3、deque的赋值操作

    deque& operator=(const deque &deq);  //重载等号操作符

    assign(beg, end);                    //将[beg, end)区间中的数据拷贝赋值给本身

    assign(n, elem);                     //将n个elem拷贝赋值给本身

    1. #include
    2. #include
    3. using namespace std;
    4. void printDeque(const deque<int> &d)
    5. {
    6. for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. deque<int>d1;
    15. for (int i = 0; i < 10; i++)
    16. {
    17. d1.push_back(i);
    18. }
    19. printDeque(d1);
    20. //operator=赋值
    21. deque<int>d2;
    22. d2 = d1;
    23. printDeque(d2);
    24. //assign赋值
    25. deque<int>d3;
    26. d3.assign(d1.begin(), d1.end());
    27. printDeque(d3);
    28. //n个elem方式赋值
    29. deque<int>d4(10, 100);
    30. printDeque(d4);
    31. }
    32. int main() {
    33. test01();
    34. system("pause");
    35. return 0;
    36. }

    4、deque的大小

    deque.empty();    //判断容器是否为空

    deque.size();      //返回容器中元素的个数

    deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置

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

    deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置

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

    1. #include
    2. #include
    3. using namespace std;
    4. void printDeque(const deque<int> &d)
    5. {
    6. for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. deque<int>d1;
    15. for (int i = 0; i < 10; i++)
    16. {
    17. d1.push_back(i);
    18. }
    19. printDeque(d1);
    20. if (d1.empty())
    21. {
    22. cout << "容器d1为空" << endl;
    23. }
    24. cout << "d1中的元素个数为:" << d1.size() << endl; //deque没有“容量”的概念
    25. d1.resize(15);
    26. printDeque(d1);
    27. d1.resize(8);
    28. printDeque(d1);
    29. d1.resize(15, 1);
    30. printDeque(d1);
    31. }
    32. int main() {
    33. test01();
    34. system("pause");
    35. return 0;
    36. }

    5、deque的插入和删除

    //两端的插入操作:

    push_back(elem);   //在容器尾部添加一个数据

    push_front(elem);   //在容器头部插入一个数据

    pop_back();        //删除容器最后一个数据

    pop_front();        //删除容器第一个数据

    //指定位置操作:

    insert(pos,elem);      //在pos位置插入一个elem元素的拷贝,返回新数据的位置

    insert(pos,n,elem);    //在pos位置插入n个elem数据,无返回值

    insert(pos,beg,end);   //在pos位置插入[beg,end)区间的数据,无返回值

    clear();              //清空容器的所有数据

    erase(beg,end);       //删除[beg,end)区间的数据,返回下一个数据的位置

    erase(pos);          //删除pos位置的数据,返回下一个数据的位置

    1. #include
    2. #include
    3. using namespace std;
    4. void printDeque(const deque<int> &d)
    5. {
    6. for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    7. {
    8. cout << *it << " ";
    9. }
    10. cout << endl;
    11. }
    12. void test01()
    13. {
    14. deque<int>d1;
    15. for (int i = 0; i < 10; i++)
    16. {
    17. d1.push_back(i); //尾插
    18. d1.push_front(i * 2); //头插
    19. }
    20. printDeque(d1);
    21. d1.pop_back();
    22. printDeque(d1);
    23. d1.pop_front();
    24. printDeque(d1);
    25. }
    26. void test02()
    27. {
    28. deque<int>d1;
    29. for (int i = 0; i < 10; i++)
    30. {
    31. d1.push_back(i);
    32. }
    33. d1.insert(d1.begin(), 30);
    34. printDeque(d1);
    35. d1.insert(d1.begin(), 2, 40);
    36. printDeque(d1);
    37. deque<int>d2;
    38. for (int i = 0; i < 10; i++)
    39. {
    40. d2.push_front(i);
    41. }
    42. d1.insert(d1.begin()+1, d2.begin(), d2.end());
    43. printDeque(d1);
    44. }
    45. void test03()
    46. {
    47. deque<int>d1;
    48. for (int i = 0; i < 10; i++)
    49. {
    50. d1.push_back(i);
    51. }
    52. d1.erase(++d1.begin());
    53. printDeque(d1);
    54. d1.erase(d1.begin(), d1.end()); //d1.clear();具有同等作用
    55. printDeque(d1);
    56. }
    57. int main() {
    58. test01();
    59. cout << endl;
    60. test02();
    61. cout << endl;
    62. test03();
    63. system("pause");
    64. return 0;
    65. }

    6、deque的数据存取

    at(int idx);  //返回索引idx所指的数据

    operator[];  //返回索引idx所指的数据

    front();     //返回容器中第一个数据元素

    back();     //返回容器中最后一个数据元素

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. deque<int>d1;
    7. for (int i = 0; i < 10; i++)
    8. {
    9. d1.push_back(i); //尾插
    10. d1.push_front(i * 2); //头插
    11. }
    12. //通过[]方式访问元素
    13. for (int i = 0; i < d1.size(); i++)
    14. {
    15. cout << d1[i] << " ";
    16. }
    17. cout << endl;
    18. //通过at方式访问元素
    19. for (int i = 0; i < d1.size(); i++)
    20. {
    21. cout << d1.at(i) << " ";
    22. }
    23. cout << endl;
    24. cout << "第一个元素为:" << d1.front() << endl;
    25. cout << "最后一个元素为:" << d1.back() << endl;
    26. }
    27. int main() {
    28. test01();
    29. system("pause");
    30. return 0;
    31. }

    7、deque的数据排序算法

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

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. void printDeque(const deque<int> &d)
    6. {
    7. for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    8. {
    9. cout << *it << " ";
    10. }
    11. cout << endl;
    12. }
    13. void test01()
    14. {
    15. deque<int>d1;
    16. for (int i = 0; i < 10; i++)
    17. {
    18. d1.push_back(i); //尾插
    19. d1.push_front(i * 2); //头插
    20. }
    21. printDeque(d1);
    22. sort(d1.begin(),d1.end()); //升序排序
    23. //对于支持随机访问的迭代器的容器,都可以用sort算法直接对其进行排序
    24. //vector容器也可以利用sort进行排序
    25. printDeque(d1);
    26. }
    27. int main() {
    28. test01();
    29. system("pause");
    30. return 0;
    31. }

    8、案例

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

    (2)实现步骤:

    ①创建五名选手,放到vector中。

    ②遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque容器中。

    ③sort算法对deque容器中分数排序,去除最高和最低分。

    ④deque容器遍历一遍,累加总分。

    ⑤获取平均分。

    (3)代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. using namespace std;
    8. /* 案例描述:有5名选手ABCDE,10个评委分别对每一名选手打分,去除最高分,去除评委中最低分,取平均分
    9. 实现步骤:
    10. 创建五名选手,放到vector中
    11. 遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque容器中
    12. sort算法对deque容器中分数排序,去除最高和最低分
    13. deque容器遍历一遍,累加总分
    14. 获取平均分*/
    15. class Person
    16. {
    17. public:
    18. Person(int score, string name)
    19. {
    20. m_name = name;
    21. m_score = score;
    22. }
    23. int m_score;
    24. string m_name;
    25. };
    26. void createPerson(vector&v)
    27. {
    28. string nameSeed = "ABCDE";
    29. for (int i = 0; i < 5; i++)
    30. {
    31. string name = "player_";
    32. name += nameSeed[i];
    33. int score = 0;
    34. Person p(score, name);
    35. v.push_back(p);
    36. }
    37. }
    38. void setScore(vector&v)
    39. {
    40. for (vector::iterator it = v.begin(); it != v.end(); it++)
    41. {
    42. deque<int>d;
    43. for (int i = 0; i < 10; i++)
    44. {
    45. int score = rand() % 51 + 50; //int score = [rand() % 51] + 50; []内取值为0~50
    46. d.push_back(score);
    47. }
    48. sort(d.begin(),d.end());
    49. d.pop_back();
    50. d.pop_front();
    51. int sum = 0;
    52. for (deque<int>::iterator dit = d.begin(); dit != d.end(); dit++)
    53. {
    54. sum += *dit;
    55. }
    56. int avg = sum / d.size();
    57. it->m_score = avg;
    58. }
    59. }
    60. void func()
    61. {
    62. vectorp;
    63. createPerson(p);
    64. setScore(p);
    65. for (vector::iterator it = p.begin(); it != p.end(); it++)
    66. {
    67. cout << it->m_name << "的最终得分为" << it->m_score << endl;
    68. }
    69. }
    70. int main() {
    71. srand((unsigned int)time(NULL));
    72. func();
    73. system("pause");
    74. return 0;
    75. }

    五、stack容器

    1、stack的基本概念

    (1)stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口。

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

    (1)栈中进入数据的过程称为入栈(push),栈中弹出数据的过程称为出栈(pop)。

    2、stack的常用接口

    //构造函数:

    stack stk;          //stack采用模板类实现,stack对象的默认构造形式

    stack(const stack &stk);  //拷贝构造函数

    //赋值操作:

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

    //数据存取:

    push(elem);   //向栈顶添加元素

    pop();        //从栈顶移除第一个元素

    top();        //返回栈顶元素

    //大小操作:

    empty();      //判断堆栈是否为空

    size();        //返回栈的大小

    1. #include
    2. #include
    3. using namespace std;
    4. void test01()
    5. {
    6. stack<int>s; //符合先进后出的数据结构
    7. s.push(10); //入栈
    8. s.push(20);
    9. s.push(30);
    10. s.push(40);
    11. while (!s.empty()) //只要栈不为空,查看栈顶,并执行出栈操作
    12. {
    13. cout << "栈顶元素为:" << s.top() << endl;
    14. s.pop(); //出栈
    15. }
    16. cout << "现在栈的大小为:" << s.size() << endl;
    17. }
    18. int main() {
    19. test01();
    20. system("pause");
    21. return 0;
    22. }

    六、queue 容器

    1、queue的基本概念

    (1)Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口。

    (2)队列容器允许从一端(队尾)新增元素,从另一端(队头)移除元素。

    (3)队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为。

    (4)数据进入队列中的过程称为入队(push),数据从队列中被移出的过程称为出队(pop)。

    2、queue的常用接口

    //构造函数:

    queue que;             //queue采用模板类实现,queue对象的默认构造形式

    queue(const queue &que);   //拷贝构造函数

    //赋值操作:

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

    //数据存取:

    push(elem);   //往队尾添加元素

    pop();        //从队头移除第一个元素

    back();       //返回最后一个元素

    front();       //返回第一个元素

    //大小操作:

    empty();     //判断堆栈是否为空

    size();       //返回栈的大小

    1. #include
    2. #include
    3. using namespace std;
    4. class Person
    5. {
    6. public:
    7. int age1;
    8. int age2;
    9. Person(int age1, int age2)
    10. {
    11. this->age1 = age1;
    12. this->age2 = age2;
    13. }
    14. };
    15. void test01()
    16. {
    17. queueq; //创建队列
    18. Person p1(10, 18); //准备数据
    19. Person p2(20, 38);
    20. Person p3(30, 58);
    21. Person p4(40, 28);
    22. q.push(p1); //入队
    23. q.push(p2);
    24. q.push(p3);
    25. q.push(p4);
    26. cout << "队列大小为:" << q.size() << endl;
    27. while (!q.empty())
    28. {
    29. cout << "队头为: age1 = " << q.front().age1 << " age2 = " << q.front().age2 << endl;
    30. cout << "队尾为: age1 = " << q.back().age1 << " age2 = " << q.back().age2 << endl;
    31. cout << endl;
    32. q.pop(); //出队
    33. }
    34. cout << "队列大小为:" << q.size() << endl;
    35. }
    36. int main() {
    37. test01();
    38. system("pause");
    39. return 0;
    40. }
  • 相关阅读:
    学习笔记|ADC|NTC原理|测温程序|STC32G单片机视频开发教程(冲哥)|第十九集:ADC应用之NTC
    c语言入门---自定义类型:结构体,枚举,联合
    selenium WebDriver 中的几种等待--sleep(),implicitly_wait(),WebDriverWait()
    mybatis03与spring的集成
    Linux安装confluence
    企业快速构建可落地的IT服务管理体系的五大关键点
    哈工大李治军老师操作系统笔记【8】:用户级线程(Learning OS Concepts By Coding Them !)
    Ms08067安全实验室成功实施多家业务系统渗透测试项目
    uni-app (通过HBuilderX 和 VS Code 开发)详细连接过程教学。
    asp毕业设计——基于asp+access的在线人才招聘网设计与实现(毕业论文+程序源码)——人才招聘网
  • 原文地址:https://blog.csdn.net/Zevalin/article/details/136221486