More detailed principle and usage of vector

More detailed principle and usage of vector

Store data

void text()
{
    // Store int type data. Of course, you can also store other types, such as char, string, class, etc
    vector<int> vec;
    vec[0] = 10;
    vec[1] = 9;
}
  1. The above storage method is wrong! It's true that vector is an array, but the initial vec has no size, so there's no way to assign values by subscript.

  2. You can print the capacity (capacity: the size of the array) and size (size: the number of elements in the array) of vec, cout < < size = "" < vec. Size() < ", capacity =" "< vec. Capacity() < < endl; The result is size = 0, capacity = 0

  3. The correct storage method is as follows:

    vector<int> vec;
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    

    Operation results:

    size = 0, capacity = 0
    size = 3, capacity = 4
    
  4. It can be found that by calling the member function push of vec_ After the back() function stores three pieces of data, the size of the vec is 3 and the capacity is 4. Some students may have been hoodwinked at that time. 4 Where did they come from? Don't worry, we'll explain the expansion mechanism of vector later! Let's start with the simplest point. Some students will say again. How do I know what member functions vec has? In fact, you can view some function related information of c + + through cppreference website. The content is very complete. Portal: https://en.cppreference.com/w/ ; It doesn't matter if you don't understand English. There is also a Chinese version https://zh.cppreference.com/w/%E9%A6%96%E9%A1%B5

  5. In fact, there is a way to assign a value to the vector array by subscript

    void test()
    {
        vector<int> vec;
        cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
        // Set the size of vec to 3, (size=capacity=3)
        vec.resize(3);
        cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
        // After vec has a size, it can be assigned by subscript
        vec[0] = 1;
        vec[1] = 2;
        cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    }
    
  6. You can also initialize the vec object directly when it is created

    // Initialize vec data
    vector<int> vec = {1, 2, 3};
    
    // You can also specify that the size of the vec is 5, and the default initial value is 0
    vector<int> vec1(5);
    
    // Specify the vec size and initialize the element to 2
    vector<int> vec2(5, 2);
    
    //Print array elements. Now we will explain how to print array elements
    for (auto elem : vec2){
            cout << elem << endl;
    }
    

Traverse vector array

Traversal mode 1 (just seen above):

vector<int> vec;
cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;

vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;

for (auto elem : vec){      
        cout << elem << endl;
}
  1. The auto keyword in the for loop is automatic type derivation in c + +. Of course, there is nothing wrong with you replacing Auto with int.

  2. You can also modify the traversal values, such as adding one to each element value

    for (int &elem : vec){
            cout << elem << endl;
            elem += 1;
    }
    
  3. Note that the for loop here has a reference & so you can modify the value. ps: a reference is an alias for a variable

Traversal mode 2: normal mode

for (size_t i = 0; i < vec.size(); ++i){
        cout << vec[i] << endl;
}
  1. Note: the judgment condition here is I < VEC. Size(), not I < VEC. Capacity(); As mentioned above, size represents the number of array elements, and capacity represents the capacity of the array. For example, if you buy a bookshelf, the bookshelf can hold 5 books, but you only put 2 books, then this 5 is the capacity of the bookshelf, and 2 represents the number of books on the current bookshelf
  2. Some students write the for loop as for (auto i = 0; i < vec.size(); + + i) and will report warning. Then i was confused and said, can't auto deduce types automatically? Why is the report type mismatched? Because you initialize i to 0, the automatically derived i is of type int. vec.size() returns size_t type (in fact, it is an unsigned long), (for the return type, you can see it clearly in cppreference)

Storage mechanism of vector

  1. Look at the code first

    vector<int> vec;
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
    vec.push_back(1);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    vec.push_back(2);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    vec.push_back(3);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    vec.push_back(4);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    vec.push_back(5);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    

    Operation results:

    size = 0, capacity = 0
    size = 1, capacity = 1
    size = 2, capacity = 2
    size = 3, capacity = 4
    size = 4, capacity = 4
    size = 5, capacity = 8
    
  2. Basically, from these data, it can be found that the size is the same as the total number of elements inserted. If an element is inserted, the size will be + 1; and the growth of capacity is 2 times the previous data capacity (it seems that windows is 1.5 times).

  3. The capacity mechanism of vector is: after the size==capacity in the array, if data needs to be stored, the system will re apply for a piece of memory space, which is twice the size before

  4. Of course, you can also use the reserve() function to specify the initial array capacity. If there is a lot of data stored, the system will expand capacity frequently at the beginning, so performance will be lost. Then you can allocate a space to the array at the beginning. If the space specified at the beginning is full and data will be stored later, expand the capacity according to twice the current capacity

    vector<int> vec;
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
    // The reserved array capacity size is 10, and only the capacity size is 10
    vec.reserve(10);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
    for (int i = 0; i < 11; ++i)
    {
        vec.push_back(i);
    }
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    

    Operation results:

    size = 0, capacity = 0
    size = 0, capacity = 10
    size = 11, capacity = 20
    

vector volume reduction

  1. If you want to save space and give up efficiency, you can also use shrink_to_fit(); to remove unused capacity

    vec.shrink_to_fit();
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
  2. To save space, you can also use the member function swap() to exchange data between two arrays

    vector<int> vec;
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
    vec.reserve(10);
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
    for (int i = 0; i < 11; ++i)
    {
        vec.push_back(i);
    }
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    
    {
        //vec1 created in the block scope is a temporary variable and is automatically destroyed when it leaves the scope
        vector<int> vec1(vec.size());
        vec1.swap(vec);  //Side effects: vec data is gone after exchange
    }
    
    cout << "size = " << vec.size() << ", capacity = " << vec.capacity() << endl;
    

My ability is limited. If there is any mistake, please correct it. The original is not easy. Welcome to reprint. Please indicate the source

Keywords: C++

Added by rubik on Tue, 07 Dec 2021 16:38:47 +0200