[Dark Horse Programmer C++ Tutorial from 0 to 1 Introduction to Programming] [Note 9] STL Standard Template Library (Standard Template Library) STL introduction, STL commonly used containers - string container, vector container

Reference article: https://www.bilibili.com/video/BV1et411b73Z?p=185

C++ STL (Standard Template Library) is part of the C++ standard library, which provides a set of general-purpose template classes and functions for implementing common data structures and algorithms, such as vectors, linked lists, heaps, stacks, queues, collections, maps , sort, find, etc. The design goal of STL is to provide efficient, reusable, and extensible code, enabling programmers to focus more on solving the problem itself rather than the implementation details of data structures and algorithms. The use of STL can greatly improve the development efficiency of the program and the maintainability of the code.

Article Directory

2 Introduction to STL

2.1 The birth of STL

  • The software world has long wanted to build something reusable

  • C++'s object-oriented and generic programming ideas aim to improve reusability

  • In most cases, there is no standard for data structures and algorithms, resulting in a lot of repetitive work

  • In order to establish a set of standards for data structures and algorithms, STL was born

2.2 Basic concepts of STL

  • STL (Standard Template Library, standard template library )
  • STL is broadly divided into: container (container) algorithm (algorithm) iterator (iterator)
  • There is a seamless connection between the container and the algorithm through an iterator .
  • Almost all code in STL uses template classes or template functions

2.3 Six major components of STL (container, algorithm, iterator, functor, adapter (adapter), space configurator)

STL is roughly divided into six major components, namely: container, algorithm, iterator, functor, adapter (adapter), space configurator

  1. Container: Various data structures, such as vector, list, deque, set, map, etc., are used to store data.
  2. Algorithms: various commonly used algorithms, such as sort, find, copy, for_each, etc.
  3. Iterator: Acts as the glue between the container and the algorithm.
  4. Functor: Behaves like a function and can be used as some kind of strategy for an algorithm.
  5. Adapter: A thing used to decorate a container or a functor or iterator interface.
  6. Space configurator: Responsible for space configuration and management.

2.4 Containers in STL (serial containers, associative containers), algorithms (qualitative algorithm, non-qualitative algorithm), iterators

Container: a place for storage

The STL container is to realize some of the most widely used data structures

Commonly used data structures: arrays, linked lists, trees, stacks, queues, collections, mapping tables, etc.

These containers are divided into two types : sequential containers and associative containers :

​Serial container : Emphasizes the sorting of values, and each element in the serial container has a fixed position.
​Associative container : binary tree structure, there is no strict physical order relationship between elements

Algorithm: the solution to the problem

Limited steps to solve logical or mathematical problems, this subject we call algorithms (Algorithms)

Algorithms are divided into: qualitative change algorithm and non-qualitative change algorithm .

Qualitative change algorithm: It means that the content of the elements in the interval will be changed during the operation. such as copy, replace, delete, etc.

Non-qualitative algorithm: It means that the content of elements in the interval will not be changed during the operation, such as searching, counting, traversing, finding extreme values, etc.

Iterator: glue between container and algorithm (commonly used: bidirectional iterator, random access iterator)

Provides a method that enables sequential access to the elements contained in a container without exposing the container's internal representation.

Each container has its own iterator

The use of iterators is very similar to pointers. At the beginning stage, we can first understand that iterators are pointers

Iterator type:

type Function Support operation
input iterator read-only access to data Read-only, supports ++, ==, !=
output iterator write-only access to data write only, supports ++
forward iterator read and write operations, and can advance the iterator Read and write, support ++, ==, !=
bidirectional iterator Read and write operations, and can operate forward and backward Read and write, support ++, –,
random access iterator Read and write operations, can access arbitrary data in a jumping way, the most powerful iterator Read and write, support ++, –, [n], -n, <, <=, >, >=

Commonly used types of iterators in containers are bidirectional iterators and random access iterators

2.5 Introduction to containers, algorithms, and iterators

After understanding the concepts of containers, algorithms, and iterators in STL, we use code to feel the charm of STL

The most commonly used container in STL is Vector, which can be understood as an array. Next, we will learn how to insert data into this container and traverse this container.

2.5.1 vector stores built-in data types

container:vector

algorithm:for_each

iterators:vector<int>::iterator

Example: four ways to traverse containers
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

void MyPrint(int val)
{
    
    
    cout << val << endl;
}

void test01()
{
    
    

    // 创建vector容器对象,并且通过模板参数指定容器中存放的数据的类型
    vector<int> v;
    // 向容器中放数据
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    v.push_back(40);

    // 每一个容器都有自己的迭代器,迭代器是用来遍历容器中的元素
    // v.begin()返回迭代器,这个迭代器指向容器中第一个数据
    // v.end()返回迭代器,这个迭代器指向容器元素的最后一个元素的下一个位置
    // vector<int>::iterator 拿到vector<int>这种容器的迭代器类型

    vector<int>::iterator pBegin = v.begin();
    vector<int>::iterator pEnd = v.end();

    // 第一种遍历方式:
    while (pBegin != pEnd)
    {
    
    
        cout << *pBegin << endl;
        pBegin++;
    }

    cout << "---------------------------" << endl;

    // 第二种遍历方式:
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
    
    
        cout << *it << endl;
    }
    cout << endl;

    cout << "---------------------------" << endl;

    // 第三种遍历方式:
    // 使用STL提供标准遍历算法  头文件 algorithm
    for_each(v.begin(), v.end(), MyPrint);

    cout << "---------------------------" << endl;

    // 第四种遍历方式:
    // 使用 auto
    for (auto i : v)
    {
    
    
        MyPrint(i);
    }

    cout << "---------------------------" << endl;
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

2.5.2 Vector stores custom data types

Learning objective: store custom data types in vector and print out

Example:

#include <vector>
#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

// 自定义数据类型
class Person
{
    
    
public:
    Person(string name, int age)
    {
    
    
        mName = name;
        mAge = age;
    }

public:
    string mName;
    int mAge;
};
// 存放对象
void test01()
{
    
    

    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 << "Name:" << (*it).mName << " Age:" << (*it).mAge << endl;
    // }

    for (auto i : v)
    {
    
    
        cout << "Name:" << i.mName << " Age:" << i.mAge << endl;
    }
    cout << "-----------------------" << 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++)
    // {
    
    
    //     Person *p = (*it);
    //     cout << "Name:" << p->mName << " Age:" << (*it)->mAge << endl;
    // }

    for (auto i : v)
    {
    
    
        cout << "Name:" << i->mName << " Age:" << i->mAge << endl;
    }
    cout << "-----------------------" << endl;
}

int main()
{
    
    

    test01();

    test02();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

2.5.3 Vector container nested container (multi-dimensional)

Learning objective: Containers are nested in containers, we will traverse all data and output

Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 容器嵌套容器
void test01()
{
    
    

    vector<vector<int>> v;

    vector<int> v1;
    vector<int> v2;
    vector<int> v3;
    vector<int> v4;

    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);
    }

    // 将容器元素插入到vector v中
    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++)
    // {
    
    

    //     for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)
    //     {
    
    
    //         cout << *vit << " ";
    //     }
    //     cout << endl;
    // }

    for (auto i : v)
    {
    
    
        for (auto j : i)
        {
    
    
            cout << j << " ";
        }
        cout << endl;
    }
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

insert image description here

3 STL-Common container

3.1 string container

3.1.1 Basic concept of string

Nature:
  • string is a C++-style string, and string is essentially a class
The difference between string and char *:
  • char * is a pointer
  • string is a class, which encapsulates char* inside the class, and manages this string, which is a container of char* type.
Features:

The string class internally encapsulates many member methods

For example: find find, copy copy, delete delete replace replace, insert insert

String manages the memory allocated by char*, so you don’t have to worry about copying out of bounds and value out of bounds, etc., and the class is responsible for it

3.1.2 String constructor

Constructor prototype:

  • string();//Create an empty string such as: string str;
    string(const char* s);//Initialize with string s
  • string(const string& str);//Use a string object to initialize another string object
  • string(int n, char c);// Initialize with n characters c
Example:
    #include <vector>
    #include <algorithm>
    #include <iostream>

    using namespace std;

    // string构造
    void test01()
    {
    
    
        string s1; // 创建空字符串,调用无参构造函数
        cout << "str1 = " << s1 << endl;

        const char *str = "hello world";
        string s2(str); // 把c_string转换成了string

        cout << "str2 = " << s2 << endl;

        string s3(s2); // 调用拷贝构造函数
        cout << "str3 = " << s3 << endl;

        string s4(10, 'a');
        cout << "str4 = " << s4 << endl;
    }

    int main()
    {
    
    

        test01();

        std::cout << "Press ENTER to continue...";
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
        return EXIT_SUCCESS;
    }

operation result:

insert image description here

Summary: The multiple construction methods of string are not comparable, just use them flexibly

3.1.3 String assignment operation (assign())

Function description:
  • assign value to string string
The function prototype of the assignment:
  • string& operator=(const char* s);//Char* type string is assigned to the current string
  • string& operator=(const string &s);//Assign the string s to the current string
  • string& operator=(char c);//Character assignment to the current string
  • string& assign(const char *s);//Assign the string s to the current string
  • string& assign(const char *s, int n);//Assign the first n characters of the string s to the current string
  • string& assign(const string &s);//Assign the string s to the current string
  • string& assign(int n, char c);// Assign n characters c to the current string
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 赋值
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++");
    cout << "str4 = " << str4 << endl;

    string str5;
    str5.assign("hello c++", 5);
    cout << "str5 = " << str5 << endl;

    string str6;
    str6.assign(str5);
    cout << "str6 = " << str6 << endl;

    string str7;
    str7.assign(5, 'x');
    cout << "str7 = " << str7 << endl;
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:
insert image description here

Summarize:

There are many assignment methods of string, operator=this method is more practical

3.1.4 string concatenation (append())

Function description:
  • Realize splicing strings at the end of strings
Function prototype:
  • string& operator+=(const char* str);// Overload += operator
  • string& operator+=(const char c);// Overload += operator
  • string& operator+=(const string& str);// Overload += operator
  • string& append(const char *s); //Connect the string s to the end of the current string
  • string& append(const char *s, int n);//Connect the first n characters of the string s to the end of the current string
  • string& append(const string &s); //同operator+=(const string& str)
  • string& append(const string &s, int pos, int n);//The n characters starting from pos in the string s are connected to the end of the string
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 字符串拼接
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 ");
    str3.append("game abcde", 4);
    // str3.append(str2);
    str3.append(str2, 4, 3); // 从下标4位置开始 ,截取3个字符,拼接到字符串末尾
    cout << "str3 = " << str3 << endl;
}
int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

Summary: There are many overloaded versions of string splicing, just remember a few at the beginner stage

3.1.5 string search and replacement (find(), rfind(), replace()) (r in rfind means reverse, reverse)

Function description:
  • Find: Find whether the specified string exists
  • Replace: replace the string at the specified position
Function prototype:
  • int find(const string& str, int pos = 0) const;//Find the first occurrence of str, starting from pos
  • int find(const char* s, int pos = 0) const; //Find the first occurrence of s, starting from pos
  • int find(const char* s, int pos, int n) const; //Find the first position of the first n characters of s from pos position
  • int find(const char c, int pos = 0) const; //Find the first occurrence of character c
  • int rfind(const string& str, int pos = npos) const;//Find the last position of str, starting from pos
  • int rfind(const char* s, int pos = npos) const;//Find the last occurrence of s, starting from pos
  • int rfind(const char* s, int pos, int n) const;//Find the last position of the first n characters of s from pos
  • int rfind(const char c, int pos = 0) const; //Find the last occurrence of character c
  • string& replace(int pos, int n, const string& str); //Replace n characters starting from pos with the string str
  • string& replace(int pos, int n,const char* s); //Replace the n characters starting from pos with the string s

Example:

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 查找和替换
void test01()
{
    
    
    // 查找
    string str1 = "abcdefgde";

    int pos = str1.find("de");

    if (pos == -1)
    {
    
    
        cout << "未找到" << endl;
    }
    else
    {
    
    
        cout << "pos = " << pos << endl;
    }

    pos = str1.rfind("de");

    cout << "pos = " << pos << endl;
}

void test02()
{
    
    
    // 替换
    string str1 = "abcdefgde";
    str1.replace(1, 1, "1111");

    cout << "str1 = " << str1 << endl;
}

int main()
{
    
    

    test01();
    test02();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

Summarize:

  • find searches from left to back, rfind from right to left
  • find returns the position of the first character found after finding the string, and returns -1 if not found
  • When replacing, you need to specify from which position, how many characters, and what kind of string to replace

3.1.6 string string comparison (compare())

Function description:
  • comparison between strings
Compare by:
  • String comparison is based on the ASCII code of the characters
= 返回   0

> 返回   1 

< 返回  -1
Function prototype:
  • int compare(const string &s) const; // compare with string s
  • int compare(const char *s) const;// compare with string s
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 字符串比较
void test01()
{
    
    

    string s1 = "hello";
    string s2 = "aello";

    int ret = s1.compare(s2);

    if (ret == 0)
    {
    
    
        cout << "s1 等于 s2" << endl;
    }
    else if (ret > 0)
    {
    
    
        cout << "s1 大于 s2" << endl;
    }
    else
    {
    
    
        cout << "s1 小于 s2" << endl;
    }
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

Summary: String comparison is mainly used to compare whether two strings are equal, and it is not very meaningful to judge who is bigger and who is smaller

3.1.7 String character access (character reading or modification) (at())

There are two ways to access a single character in string

  • char& operator[](int n); //Get characters by []
  • char& at(int n); / / Get the character through the at method
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

void test01()
{
    
    
    string str = "hello world";

    for (int i = 0; i < str.size(); i++)
    {
    
    
        cout << str[i];
    }
    cout << endl;

    for (int i = 0; i < str.size(); i++)
    {
    
    
        cout << str.at(i);
    }
    cout << endl;

    // 字符修改
    str[0] = 'x';
    str.at(1) = 'x';
    cout << str << endl;
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

Summary: There are two ways to access a single character in a string, using [ ]orat

3.1.8 string insertion and deletion (insert(), erase())

String insertion is equivalent to the second parameter of the replace function being 0, that is, replacing out of thin air

Function description:
  • Insert and delete characters on the string string
Function prototype:
  • string& insert(int pos, const char* s); //insert string
  • string& insert(int pos, const string& str); //insert string
  • string& insert(int pos, int n, char c);//Insert n characters c at the specified position
  • string& erase(int pos, int n = npos);//Delete n characters starting from Pos
About string& erase(int pos, int n = npos);_npos

npos is a static member variable of the string class in the C++ standard library, which represents an infinite value, and is usually used to represent the end position of the string. In the string& erase(int pos, int n = npos) function, if the value of n is not specified, all characters from position pos to the end of the string will be deleted by default. Therefore, the role of npos here is to indicate the position of the end of the string, so as to specify the range of deletion.

Example:

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 字符串插入和删除
void test01()
{
    
    
    string str = "hello";
    str.insert(1, "111");   //相当于str.replace(1, 0, "111");
    // str.replace(1, 0, "111");
    cout << str << endl;

    str.erase(1, 3); // 从1号位置开始3个字符
    cout << str << endl;
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

Summary: The starting subscripts of insertion and deletion start from 0

3.1.9 string substring (substr())

Function description:
  • Get the desired substring from a string
Function prototype:
  • string substr(int pos = 0, int n = npos) const;//Returns a string consisting of n characters starting from pos

Note: The substr parameter is a left-open and right-close interval, ie[pos, npos)

Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// 子串
void test01()
{
    
    

    string str = "abcdefg";
    string subStr = str.substr(1, 3);
    cout << "subStr = " << subStr << endl;

    string email = "[email protected]";
    int pos = email.find("@");
    cout << "pos = " << pos << endl;
    string username = email.substr(0, pos);
    cout << "username: " << username << endl;
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

operation result:

insert image description here

Summary: Flexible use of the substring function can obtain effective information in actual development

3.2 vector container

3.2.1 Basic concept of vector

Function:

  • The vector data structure is very similar to an array , also known as a single-ended array
The difference between vector and ordinary array:
  • The difference is that the array is a static space, and the vector can be dynamically expanded
The principle of dynamic expansion: instead of adding a new space after the original space, a larger memory space is found, and then the original data is copied to the new space to release the original space

insert image description here

  • The iterator of the vector container is an iterator that supports random access

3.2.2 vector constructor

Function description:
  • Create a vector container
Function prototype:
  • vector<T> v; //Template implementation class implementation, default constructor
  • vector(v.begin(), v.end()); //Copy the elements in the interval v[begin(), end()) to itself.
  • vector(n, elem);//The constructor copies n elems to itself. (Create an array with n elem elements)
  • vector(const vector &vec);// Copy constructor.
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

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);

    vector<int> v2(v1.begin(), v1.end());
    printVector(v2);

    vector<int> v3(10, 100); // 创建10个值为100的元素的数组
    printVector(v3);

    vector<int> v4(v3);
    printVector(v4);
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

Reference article:

insert image description here

Summary: The multiple construction methods of vector are not comparable, just use them flexibly

3.2.3 Vector assignment operation (assign)

Function description:
  • Assign a value to the vector container

Function prototype:

  • vector& operator=(const vector &vec);// Overload the equals operator

  • assign(beg, end);//Assign the copy of the data in the interval [beg, end) to itself.

  • assign(n, elem);// Assign n elem copies to itself.

Example:

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

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);

    vector<int> v2;
    v2 = v1;
    printVector(v2);

    vector<int> v3;
    v3.assign(v1.begin(), v1.end());
    printVector(v3);

    vector<int> v4;
    v4.assign(10, 100); // 赋予数组10个值为100的元素
    printVector(v4);
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

insert image description here

Summary: The vector assignment method is relatively simple, you can use operator= or assign

3.2.4 Vector capacity and size (empty(), capacity(), size(), resize() (change size instead of capacity))

Function description:
  • Capacitance and size operations on vector containers
Function prototype:
  • empty(); // Check if the container is empty

  • capacity();//capacity of the container

  • size();//returns the number of elements in the container

  • resize(int num);//Respecify the length of the container as num, if the container becomes longer, fill the new position with the default value.

    ​ //If the container becomes shorter, the elements at the end that exceed the length of the container are deleted.

  • resize(int num, elem);//Respecify the length of the container as num. If the container becomes longer, fill the new position with the value of elem.

    // If the container becomes shorter, the elements at the end that exceed the length of the container are deleted

Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

void printVector(vector<int> &v)
{
    
    

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
    
    
        cout << *it << " ";
    }
    cout << endl;

    if (v.empty())
    {
    
    
        cout << "v为空" << endl;
    }
    else
    {
    
    
        cout << "v不为空" << endl;
        cout << "v的容量 = " << v.capacity() << endl;
        cout << "v的大小 = " << v.size() << endl;
    }
}

void test01()
{
    
    
    vector<int> v1;
    for (int i = 0; i < 10; i++)
    {
    
    
        v1.push_back(i);
    }
    printVector(v1);

    cout << "------------------------" << endl;

    // resize 重新指定大小 ,若指定的更大,默认用0填充新位置,可以利用重载版本替换默认填充
    v1.resize(15, 10); // 以元素10填充
    printVector(v1);

    cout << "------------------------" << endl;

    // resize 重新指定大小 ,若指定的更小,超出部分元素被删除
    v1.resize(5);
    printVector(v1);

    cout << "------------------------" << endl;
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

insert image description here

Summarize:

  • Determine whether it is empty—empty
  • Returns the number of elements — size
  • Returns the container capacity — capacity
  • Resize — resize

3.2.5 Vector insertion and deletion (push_back(), pop_back(), insert(), erase(), clear())

Function description:
  • Insert and delete operations on vector containers
Function prototype:
  • push_back(ele);//Insert element ele at the end
  • pop_back();// delete the last element
  • insert(const_iterator pos, ele);//The iterator points to the position pos to insert the element ele (inserted before the current subscript element)
  • insert(const_iterator pos, int count,ele);//The iterator points to position pos and inserts count elements ele
  • erase(const_iterator pos);// delete the element pointed to by the iterator
  • erase(const_iterator start, const_iterator end);//Delete the elements from the iterator from start to end
  • clear();// delete all elements in the container
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

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, 1000); // 插入两个1000
    printVector(v1);

    // 删除
    v1.erase(v1.begin());
    printVector(v1);

    // 清空
    v1.erase(v1.begin(), v1.end());
    v1.clear();
    printVector(v1);
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

insert image description here

Summarize:

  • Tail plug — push_back
  • Tail delete — pop_back
  • insert — insert (position iterator)
  • delete — erase (position iterator)
  • Empty—clear

3.2.6 Vector data access (read and modify) (at(), front(), back())

Function description:
  • Access to data in vector
Function prototype:
  • at(int idx); //Return the data pointed to by the index idx
  • operator[]; //Return the data pointed to by the index idx
  • front(); //returns the first data element in the container
  • back();//returns the last data element in the container
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

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;

    for (int i = 0; i < v1.size(); i++)
    {
    
    
        cout << v1.at(i) << " ";
    }
    cout << endl;

    cout << "v1的第一个元素为: " << v1.front() << endl;
    cout << "v1的最后一个元素为: " << v1.back() << endl;
}

int main()
{
    
    

    test01();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

insert image description here

Summarize:

  • In addition to using iterators to get elements in the vector container, [ ] and at can also
  • front returns the first element of the container
  • back returns the last element of the container

3.2.7 vector swap container (swap()) (swap() can be used to shrink memory for anonymous objects)

Function description:
  • To achieve the exchange of elements in two containers
Function prototype:
  • swap(vec);// swap vec with its own elements
Example:
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

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);

    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);

    cout << "---------------------" << endl;
}

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;
    cout << "v的大小为:" << v.size() << endl;

    // 收缩内存
    vector<int>(v).swap(v); // 匿名对象
    cout << "收缩内存后:" << endl;
    cout << "v的容量为:" << v.capacity() << endl;
    cout << "v的大小为:" << v.size() << endl;

    cout << "---------------------" << endl;
}

int main()
{
    
    

    test01();

    test02();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

insert image description here

Summary: swap can make two containers interchangeable, which can achieve a practical effect of shrinking memory

3.2.8 vector reserved space (reserve() function) (note: when the vector array space is not enough, the memory space will be reallocated, the original elements will be copied to the new memory space, and the original memory space will be released; if At the beginning, use the reserve() function to allocate a large enough space, which will reduce the number of vector expansions when dynamically expanding the capacity)

Function description:
  • Reduce the number of expansions of vector when dynamically expanding capacity
Function prototype:
  • reserve(int len);//The container reserves len element length, the reserved position is not initialized, and the element is inaccessible.
Example (vector's expansion strategy is to expand according to certain rules, and the size of each expansion is twice the original size)

Note: When the number of elements in the vector exceeds its current capacity, the vector will reallocate the memory space, copy the original elements to the new memory space, and release the original memory space. This process will cause the first address of the vector to change. In order to avoid frequent memory allocation and release, you can use the reserve function to reserve a certain amount of memory space to avoid frequent reallocation of memory space by vector.

Vector's expansion strategy is to expand according to certain rules, and the space for each expansion is twice the original size

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

void test01()
{
    
    
    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;
}

void test02()
{
    
    
    vector<int> v;

    // 预留空间
    v.reserve(10);

    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();

    std::cout << "Press ENTER to continue...";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 读取内容直到用户输入enter键
    return EXIT_SUCCESS;
}

insert image description here

explain:

In test02(), although we only reserved 10 spaces, we pushed_back a total of 100,000 elements in the loop. At this time, the vector will automatically expand, and each expansion will re-allocate a larger memory space, and Copy the original elements to the new memory space, so there will be multiple operations of reallocating memory. However, because the expansion strategy of vector is to expand according to certain rules, the size of each expansion is twice the original size, so the number of memory reallocations is actually limited. In this example, since we have reserved 10 spaces from the beginning, vector will use up these 10 spaces when it push_back for the first time, and then expand to 20 spaces, and then expand to 40 spaces. And so on, until the capacity is expanded to the final 131072 spaces. Therefore, the number of reallocations of memory is actually only 15 times.

Summary: If the amount of data is large, you can use reserve to reserve space at the beginning

Guess you like

Origin blog.csdn.net/Dontla/article/details/130465021