Use of vector in C ++
Vector is the most common container in STL. It is an ordered container that supports random access. Simply put, vector is a dynamic array that can store any type of data, but the array is a static allocation space. Once the space is allocated, the size cannot be changed, but the vector is dynamically allocated memory, with the continuous insertion of elements, it will expand its capacity according to its own mechanism.
Vector Expansion Mechanism: Increase by double the current container capacity. The vector container allocates a continuous memory space. The growth of each container does not simply overlay the continuous memory space of crude oil, but re-applies for a larger new memory, copy the elements in the existing container one by one, and then destroy the old memory. The iterator that originally points to the old memory space has expired. Therefore, when operating the container, the iterator should be updated in time.
Vector is a class template. You can use a class template to write a type definition or function definition for multiple different data types. Therefore, a vector is not a data type, but a class template that can be used to define any number of data types. Each of the vector types sets the type of elements it stores.
When we want to use vector, we must add # include to the header file.
Vector belongs to the std naming field and needs to be defined by naming,
using std::vector;vector
vInts;
Or, use the full name
std::vector
vInts;
You can also use the global naming domain:
using namespace std;
Vector Initialization
# Include
# Include
Using namespace std; int main () {vector
Vec1; // create an empty vector
Vec2 (vec1); // copy vec1 vector
Vec3 (10); // creates a vector Containing n pieces of data. The data is constructed by default to generate a vector.
Vec4 (10, 1); // create a vector containing 10 1}
Vector operations
Vec. assign (beg, end); vec. assign (n, elem); // value the data in the [beg; end) interval to c. Assign a copy of n elem values to c. Vec. at (idx) // returns the data indicated by index idx. If idx is out of bounds, out_of_range is thrown. Vec. back () // returns the last data and does not check whether the data exists. Vec. begin () // return the first data address in the iterator. Vec. capacity () // return the current allocated capacity of the container. Vec. clear () // remove all data from the container. Vec. empty () // determines whether the container is empty. Vec. end () // points to the next of the end Element in the iterator, pointing to a nonexistent element. Vec. erase (pos) // Delete the data at the pos location and return the next data location. Vec. erase (beg, end) // Delete the data in the [beg, end) interval and return the next data location. Vec. front () // returns the first data. Get_allocator // use the constructor to return a copy. Vec. insert (pos, elem) // insert an elem copy at the pos position to return the new data location. Vec. insert (pos, n, elem) // insert n elem data at the pos position. No return value. Vec. insert (pos, beg, end) // insert data in the [beg, end) interval at the pos position. No return value. Vec. max_size () // returns the maximum number of data in the container. Vec. pop_back () // Delete the last data. Vec. push_back (elem) // Add a data at the end. Vec. rbegin () // returns the first data of a reverse queue. Vec. rend () // returns the next location of the last data in the reverse queue. Vec. resize (num) // specify the queue length again. Vec. reserve () // retain the appropriate capacity. Vec. size () // returns the actual number of data in the container. Vec1.swap (vec2) swap (vec1, vec2) // swap c1 and c2 elements. Same as above.
The following are operations on some member functions:
# Include
# Include
// The header file using namespace std; int main () {// Several vector declarations vector
V1; // defines an empty vector
V2 (10); // generates a vector of 10
V3 (10,-1); // The generated size is 10, and each element is a-1 vector.
V4 (v3); // use a vector to generate a vecotr int arr [5] = {1, 2, 4, 5}; vector
V5 (arr, & arr [5]); // vector cout with the interval [beg; end) as the initial value <"Current element quantity" <
: Iterator ita; // declare an iterator int I = 0; for (ita = v1.begin (), I = 0; ita! = V1.end (); I ++, ita ++) // v1.begin () points to the first element of v1, v1.end () point to the next position of the last element {cout <"v1" <
: Reverse_iterator ita; v2 = v1; // copy all v1 elements to v2 for (ita = v2.begin (), I = 0; ita! = V2.end (); I ++, ita ++) {cout <"v2" <
: Iterator pos = v1.begin (); v1.insert (pos, 11); // v1.insert (pos,); // if used directly, it is incorrect, the iterator is invalid. // v1.insert (pos, arr, & arr [5]); for (ita = v1.begin (), I = 0; ita! = V1.end (); I ++, ita ++) {cout <"v1" <
The following content is from others
Memory Management and Efficiency
1. Use the reserve () function to set the capacity in advance to avoid inefficiency caused by multiple capacity expansion operations.
One of the most commendable features of STL containers is that they can automatically grow to be enough to accommodate the data you put in as long as they do not exceed their maximum size. (To know the maximum value, you only need to call the member function named max_size .) For vector and string, if more space is needed, increase the size in a way similar to realloc. The vector container supports random access. Therefore, to improve efficiency, it uses dynamic arrays internally. When applying for a specific size through reserve (), the internal buffer is always increased by exponential boundary. When adding elements such as insert or push_back, if the memory of the dynamic array is insufficient at this time, it is necessary to dynamically re-allocate the current size of 1.5 ~ 2 times the new memory zone, and then copy the content of the original array. Therefore, in general, the access speed is the same as that of the general array, and its performance will decrease only when reallocation occurs. As the code above tells you. In the pop_back operation, capacity does not decrease because the elements in the vector container are reduced, and the size before the operation is maintained. For a vector container, if a large amount of data requires push_back, you should use the reserve () function to set its capacity in advance. Otherwise, many capacity expansion operations may occur, resulting in low efficiency.
The reserve member function allows you to minimize the number of times that must be re-allocated, so you can avoid overhead of true allocation and expiration of iterator/pointer/reference. But before I explain why reserve can do that, let me briefly introduce the four sometimes confusing member functions. In standard containers, only vector and string provide all these functions.
(1) size () indicates the number of elements in the container. It does not tell you how much memory the container has allocated to its elements. (2) capacity () tells you how many elements the container can accommodate in its allocated memory. That is how many elements the container can accommodate in that memory, rather than how many elements it can accommodate. If you want to know how much memory is not occupied in a vector or string, you must subtract size () from capacity (). If size and capacity return the same value, there is no space left in the container, and the next insertion (through insert or push_back) will lead to the above re-allocation step. (3) resize (Container: size_type n) forces the Container to accommodate n elements. After resize is called, size returns n. If n is smaller than the current size, the elements at the end of the container are destroyed. If n is greater than the current size, the new default element is added to the tail of the container. If n is greater than the current capacity, it will be reassigned before the element is added. (4) reserve (Container: size_type n) forces the Container to change its capacity to at least n, and the provided n is not smaller than the current size. This forces a redistribution because the capacity needs to increase. (If n is smaller than the current capacity, vector ignores it. This call does nothing. string may reduce its capacity to size () and n in large numbers, however, the size of the string is not changed. In my experience, it is generally better to use reserve to Trim excess capacity from a string than to use "exchange skills", which is the subject of Clause 17 .)
This introduction indicates that as long as there are elements to be inserted and the container capacity is insufficient, they will be re-allocated (including the original memory allocated and recycled they maintain, object copy and analysis structure and iterator, pointer and reference failure ). Therefore, the key to avoiding reallocation is to use reserve to set the container capacity to large enough as soon as possible. It is best to do so immediately after the container is constructed.
For example, suppose you want to create a vector containing 1-Values
. If reserve is not used, you can do it like this:
Vector
V; for (int I = 1; I <= 1000; ++ I) v. push_back (I); in most STL implementations, this code will cause two to ten reallocation during the loop process. (10 is nothing strange. Remember that when the redistribution happens, the vector generally doubles the capacity, and 1000 is about 210 .)
Change the code to use reserve. We get this:
Vector
V; v. reserve (1000); for (int I = 1; I <= 1000; ++ I) v. push_back (I); this will not happen in the loop.
The relationship between size and capacity allows us to predict when insertion will cause the vector or string to be re-allocated, and, it can be predicted when insertion will invalidate the iterator, pointer, and reference pointing to the container. For example, the following code is provided,
String s ;... if (s. size () <s. capacity () {s. push_back ('x');} the call to push_back does not invalidate the iterator, pointer, or reference pointing to this string, because the size of the string must be greater than its size. If push_back is not executed and the code performs an insert operation at any position of the string, we can still ensure that no redistribution occurs during the insertion. However, it is consistent with the general rule that the iterator becomes invalid when it is inserted with string. All iterators, pointers, and references from the inserted position to the end of the string will become invalid.
Back to the purpose of these terms, reserve is usually used in two cases to avoid unnecessary redistribution. The first available scenario is when you know exactly or approximately how many elements will last in the container. In that case, just like the vector code above, you just reserve the appropriate amount of space in advance. The second case is to keep the maximum space you may need, and then, once you add full data, trim any excess capacity.
2. Use swap techniques to Trim excess space/memory of a vector
There is a way to reduce it from its largest capacity to its current capacity. This method of capacity reduction is often called "shrink to fit )". This method requires only one statement: vector
(Ivec). swap (ivec); Expression vector
(Ivec) creates a temporary vector, which is a copy of ivec: The copy constructor of the vector. However, the copy constructor of the vector only allocates the memory required for the copied elements, so this temporary vector has no additional capacity. Then we have the temporary vector and ivec exchange data, and now we have done it. ivec only has the capacity that the temporary variable has been trimmed, this temporary variable holds the excess capacity that was never used in ivec. Here (the end of this statement), the temporary vector is destroyed, so the memory used by ivec is released and reduced to the appropriate one.
3. Use the swap method to forcibly release memory occupied by STL Vector
Template <class T> void ClearVector (vector
& V) {vector
VtTemp; vtTemp. swap (v);} such as vector
V; nums. push_back (1); nums. push_back (3); nums. push_back (2); nums. push_back (4); vector
(). Swap (v );
/* Or v. swap (vector
());*/
/* Or {std: vector
Tmp = v; v. swap (tmp) ;}; // Add braces {} to enable automatic structure analysis when tmp exits */