Vector
Vectors are collections of objects of the same type. Each object in the collection has a corresponding index. Vectors are often referred to as containers (container).
To use vectors, you need to:
#include <vector>
using Std::vector;
The vector is a class template (classes template). C + + has functional templates and class templates. The template itself is not a function or class, it must be instantiated by the compiler (instantiation) by the specified type. Like Vector<int> Ivec.
Vectors are templates, not types. The type derived from the vector is to contain the type of the element.
Early C + + definition vector is the vector is the last closing parenthesis must have a space before, such as vector<vector<int> >. But C + + 11 does not require this.
defining and initializing vectors
The most common way to define vectors is as follows:
Method |
explain |
Vector v1 |
Default initialization, V1 is empty |
Vector v2 (v1) |
V2 has v1 copy of each element |
Vector v2 = v1 |
Equivalent to v2 (v1) | |
Vector v3 (N, Val) |
V3 has n val |
Vector v4 (n) |
V3 has n elements, each element is value-initialized |
Vector v5{a, B, C, ...} |
The elements of V5 are a, B, C, ... |
Vector v5 = {A, B, C, ...} |
Equivalent to V5{a, B, C, ...} |
It should be noted that the most common method of using vectors is to define a vector that was initially empty, that is, Vector<t> V, which specifies elements at run time.
List initialization of vectors (list initializing)
The above method of using curly braces (curly brace) is list initialization, which is introduced by C + + 11.
Like what
Vector<string> articles = {"An", "a", "the"};
We see C + + There are many ways to initialize, in many cases they can be interchangeable, but sometimes the form of initialization cannot be changed:
When using a copy initialization form (that is, using =), only a single initializer can be provided
When In-class initialization is provided, only copy initialization or curly braces
List initialization can only use curly braces, not parentheses
About Value-initialized
As mentioned earlier, vector<int> Ivec (10) is an initialization method that specifies only the number of elements, each of which is a value-initialized. That
For built-in types, the value is 0
For class types, use default initialization
Curly braces, round brackets
Vector<int> v1 (10); 10 elements, all 0
vector<int> v1{10};//1 elements,
vector<int> v1{10, 1};//2 elements, respectively, 1
vector< Int> v1 (10, 1); 10 elements, all 1.
It should be noted that using {} is not necessarily the list initialization; It says: If possible, use list initialization.
vector<string> v5{"Hi"}; OK, List initialization
vector<string> V6 ("HI");//Error:cann ' t construct vector from string lieral
VEC Tor<string> v7{10}; has ten default-initialized value.
The V7 above uses curly braces to specify the number instead of the list initialization.
adding elements to vectors
Use the Push_back method.
Important concept: vector efficient growth:
The standard requires that the vector's implementation be added efficiently at run time. If you specify a size when you define a vector, it is unnecessary or even results in poor performance. In short, the general directly begins to define an empty vector.
In addition, we want to make sure that loops are correct even if the loop changes the size of the vector. Therefore, you cannot add elements to the vector in the range for.
Other vector operations
The most common operations are:
Method |
V.empty () |
V.size () |
V.push_back (t) |
V[n] |
= =,!=, <=, >= |
Similarly, the type returned by V.size () is also size_type. It should be noted that the type of the template class is always inclusive of the element type.
Vector<int>::size_type//OK
vector::size_type//Error
For subscript access, it can only access elements that already exist and will not be added.
Vector<int> Ivec;
cout << ivec[0]; Error for
(Decltype (Ivev.size ()) IX = 0; IX!= ix++)
Ivec[ix] = IX;//Disaster:has no element
iterators
Although we can use subscripts to access characters or vector elements in a string, a more general mechanism is to use iterators (iterator).
All containers support iterators, but only a few support subscript operations.
Valid iterators:
- Indicates an element
- Indicates the next position of the last element
- Other iterators are illegal.
- Using iterators
Use the Begin and end member functions.
b indicates the first element; E indicates the next position of the last element
Auto B = V.begin (), E = V.end ();
Generally we don't have to care about the exact type of the iterator, so use auto directly.
End the iterator returned is generally referred to as a off-the-end iterator, or abbreviated as an end iterator.
Obviously, if a container is empty, begin returns the same as end.
actions of Iterators
| Method | Explain | | ITER | Returns a reference to an element | | Iter->mem | dereference iter, and get a member with the name Mem, equivalent to (ITER). Mem | | ++iter | Add iter, instruct next | | --iter | Reduce ITER, indicating the previous one | | == , != | Compare |
The following is to capitalize the characters before you encounter whitespace characters.
for (Auto it = S.begin (); it!= s.end () &&!isspace (*it); ++it)
*it = ToUpper (*it);
People who are familiar with C or the Java language may need to be accustomed to C + + for loops typically end with!= instead of using <. This is because all of the container's iterators define the!= and = = methods, while most of the iterators do not have < methods. By using!=, we do not have to care about the exact type of handling containers.
Type of iterator
Just as we do not know the exact type of vector or string size_type, we generally do not know the exact type of the iterator.
The iterator for a library type defines two types of iterator and const_iterator.
Vector<int>::iterator it; Readable, writable
vector<int>::iterator it2;//readable, writable
vector<int>::const_iterator it3;//readable, unable to write
Const_iterator behaves like a const pointer. Just like the const pointer, const_iterator cannot modify the indicated element. If a vector or a string is const, you can only use Const_iterator.
If the object is const, then the begin and end return is const_iterator; If the object is not const, the return is iterator. But this behavior is sometimes not what we want, that is, for non-const objects, we also want to get const_iterator. C + + 11 introduced two new functions, cbegin and cend solve this problem.
Dereference and Access members
When you dereference an iterator, you get the object that it indicates. If the object is of a class type, we might want to access its members. For example, a vector of a string might want to know whether a given element is empty and can be used (*it). Empty ().
It should be noted that (*it). Empty () This bracket is required. Otherwise, the DOT operator works directly on it. Therefore, *it.empty () is wrong.
To simplify this representation, the language defines the arrow operator (->), which combines the dereference and member access into a single symbol, It->empty ().
Arithmetic of iterators
Self-increase and self-subtraction are operations supported by all iterators.
Additional arithmetic operations are also supported for strings and Vector iterators.
| Method | | ITER + n | | Iter-n | | Iter1 + N | | Iter2-= n | | Iter1-iter2 | | ", >=, <= |
For example, to compute the middle position of a vector,
Auto mid = Vi.begin () + vi.size ()/2;
It should be noted that the addition of iterators is illegal.