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; }
-
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.
-
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
-
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
-
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
-
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; }
-
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; }
-
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.
-
You can also modify the traversal values, such as adding one to each element value
for (int &elem : vec){ cout << elem << endl; elem += 1; }
-
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; }
- 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
- 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
-
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
-
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).
-
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
-
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
-
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;
-
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