After explaining the various containers, I believe you have some knowledge about the iterator. The iterator is one of the several major modules in STL (System Tools, containers, iterators, algorithms, there is no doubt about the importance of the function imitation, string and iostream. Now we will discuss in detail the usage of the iterator in STL.
Motivation of the iterator:
In the early implementation of STL, containers and algorithms were merged, that is, each container had its own exclusive algorithm, but later found that this efficiency was not high, in addition, many algorithms of each container are roughly the same, so the STL designer came up with the idea of separating the algorithm from the container, that is, the algorithm is only written once, and each container can call it. Therefore, an intermediate variable must be used as a bridge between the container and the algorithm. As a result, the iterator came into being.
Note that the above chart relationship does not represent an inherited relationship, but the following is the above expanded set.
(Because only the last two types of iterators are used in STL, the first three are briefly described)
Input_iterator (input iterator): The input iterator can read elements only one step forward, and only one position can be read once.
Output_iterator (output iterator): the output iterator can only be used to write elements one step forward, and only one position can be written once.
Forward_iterator (backward iterator): The forward iterator can basically do everything that the input and output iterator can do. It can be read, written, and multiple times, but what remains unchanged is that we can only move forward step by step and cannot cross.
Bidirectional iterators: the bidirectional iterator is modified based on the forward iterator, and the backward operation is added, at the same time, it saves all the features of the forward iterator, but it can only be performed one step at a time and cannot be crossed. The list set Multiset map multimap container is supported.
Note: The bidirectional iterator itself can only support ++ --! = Operation, cannot be used as follows:
List <int> Coll;
List <int>: iterator it;
For (IT = Coll. Begin (); It <Coll. End (); It + 1) // Error
'''''''''''''''''''''''''''''''''''''''
The first error is it <Coll. End (); the two-way iterator does not support the <operator.
The second error is it + 1. The bidirectional iterator can only be it ++.
Therefore, it must be written as follows:
For (IT = Coll. Begin (); it! = Coll. End (); It ++)
In fact, it cannot be imagined that the list is implemented by the linked list. The elements accessed by the linked list at any position can only be read from the header in sequence and cannot be accessed directly. The other containers are similar.
Random access iterators (Random Access iterator ):
The Random Access iterator adds the random access capability based on the two-way iterator. It can increase or subtract an offset to handle the distance problem and use the <> operator, you can also randomly access or modify an element like an array, which is the highest evolutionary version of the current iterator. If you change the list in the above error example to vector, it is correct. The Random Access iterator is consistent with the operation supported by common pointers. The supported container is vector deque ..
Several auxiliary functions of the iterator:
1: Advance () allows the iterator to move forward or backward.
Template <class init, class Dist>
Void advance (init & it, dist n );
The first parameter is the passed-In iterator, and the second parameter is generally an integer. If it is positive, it indicates the forward N bits. Otherwise, the return N bits. (In the iterator, moving backward indicates moving forward, and moving forward indicates moving backward)
2: distance () can process the positions between two iterators.
Template <class init, class Dist>
Ptrdiff_t distance (init first, init last );
This function is used to input two iterators and return the distance between them. However, make sure that the two iterators must be on the same container. Otherwise, undefined behavior is caused.
3: iter_swap can exchange the values specified by the two iterators (the positions of the iterator remain unchanged)
Template <class fwdit1, class fwdit2>
Void iter_swap (fwdit1 X, fwdit2 y );
The two parameters are two iterators, and the value after execution is switched.
I believe that, you may wonder why the Random storage iterator can directly subtract the distance, add the distance, or exchange the distance, in fact, these functions are mainly used for non-random access iterators, because they do not own these functions. When they are used for random access iterators, they perform the same operations as what we do, it has constant complexity and is used for two-way iterators with logarithm complexity.
The following is a simple example:
# Include <iostream>
# Include <vector>
# Include <list>
# Include <algorithm>
Using namespace STD;
Int main ()
{
Vector <int> VEC;
List <int> Lis;
For (INT by = 1; by <21; ++)
{
VEC. push_back ();
Lis. push_back ();
}
Vector <int>: iterator it1, it2;
List <int >:: iterator io1, io2;
Cout <"usage of distance ():" <Endl;
It1 = find (VEC. Begin (), VEC. End (), 3 );
Io1 = find (LIS. Begin (), Lis. End (), 3 );
It2 = find (VEC. Begin (), VEC. End (), 13 );
Io2 = find (LIS. Begin (), Lis. End (), 13 );
Cout <"location in vector:" <(it2-it1) <Endl;
Cout <"location in list:" <distance (io1, io2) <Endl;
Cout <"usage of advance ():" <Endl;
Cout <"distance in the vector:" <(it2 + 3)-(it1 + 2) <Endl;
Advance (io1, 2 );
Advance (io2, 3 );
Cout <"location in list:" <distance (io1, io2) <Endl;
Cout <"usage of iter_swap ():" <Endl;
Cout <"using intermediate variable exchange in vector" <Endl;
Int mid;
Mid = * (it1 + 2 );
* (It1 + 2) = * (it2 + 3 );
* (It2 + 3) = mid;
Copy (VEC. Begin (), VEC. End (), ostream_iterator <int> (cout ,""));
Cout <Endl;
Cout <"using iter_swap () Exchange in list:" <Endl;
Iter_swap (io1, io2 );
Copy (LIS. Begin (), Lis. End (), ostream_iterator <int> (cout ,""));
Cout <Endl;
System ("pause ");
Return 0;
}
In this example, the numbers 1 to 20 are stored in two different types of containers (of course, this mainly refers to their different iterators ). Locate the iterator positions 3 and 13 respectively, and the distance can be directly subtracted from the vector. The list can only use the distance function to offset the same unit and calculate the distance. Finally, the positions of 16 and 5 are changed.
This small program is very simple, but the differences between the two iterators are obvious. Generally, we use only two-way iterators for the auxiliary functions of the iterator, because the random access iterator is unnecessary, it depends on the actual situation! At this point, the main problem is to understand the differences between the random access iterator and the two-way iterator. We will also mention more differences between them in the algorithm.