Just as STL encapsulates a lot of data structures for us, STL also provides us with many common algorithms, such as sorting and searching. These algorithms are actually a function template. They are implemented through the iterator and template instead of specific types. For general algorithms, there is an important concept here: the algorithm will never execute the Container operation, but will only use the iterator to execute its logic, it will never directly call the functions of the container. If we provide the original iterator for the algorithm, the algorithm will never change the size of the underlying container.
The algorithm library provided by STL is huge and it is very difficult to write down so many algorithms. Fortunately, almost all of its algorithms follow the following structure:
[Cpp]
Alg (beg, end, other parms );
Alg (beg, end, dest, other parms );
Alg (beg, end, beg2, other parms );
Alg (beg, end, beg2, end2, other parms );
Among them, parameters such as beg, end, beg2, end2, and dest all refer to the iterator.
To learn the STL algorithm, we still start with the most basic query algorithm. Its declaration form is as follows:
[Cpp]
Template <class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T & value );
It can be seen that the find function belongs to the first common algorithm, and its function is to find the element with the value equal to the value within the sequence range specified by the first two parameters, and return its iterator. This version of the find function requires that its element type must support = or! = Operator.
For search algorithms, STL provides find_first_of (similar to string: find_first_of) and find_if.
Next, let's talk about the sorting algorithm. All the iterator types required by the sorting algorithm provided by STL must be random iterators (refer to my previous note ). The following table lists the sorting algorithms provided by STL:
Function Name
Function Description
Sort
Sorts all elements in a given range.
Stable_sort
Performs a stable sorting of all elements in a given range.
Partial_sort
Sorts all elements in a given range.
Partial_sort_copy
Copy and sort a given interval
Nth_element
Find the elements corresponding to a location in a given range
Is_sorted
Determine whether the order of an interval has been sorted
Partition
Place elements that meet certain conditions in front of them.
Stable_partition
Relatively stable putting elements that meet certain conditions in front
The stable modifier indicates that the Sorting Algorithm is stable, that is, the original sequence of equal elements is not changed.
Taking sort as an example, let's take a look at its declaration form:
[Cpp]
Template <class RandomAccessIterator>
Void sort (RandomAccessIterator first, RandomAccessIterator last );
Template <class RandomAccessIterator, class Compare>
Void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp );
The first and last iterators limit the sorting range. The first version requires that the basic element type must support the <operator. In the second version, the displayed comparison function is passed through the third parameter for comparison during sorting. Most of the declaration forms of other sorting algorithms are similar to those described here. For details, refer to the help documentation.
Next, let's take a look at the accumulation algorithm. Let's first look at its declaration form:
[Cpp]
Template <class InputIterator, class T>
T accumulate (InputIterator first, InputIterator last, T init );
Template <class InputIterator, class T, class BinaryOperation>
T accumulate (InputIterator first, InputIterator last, T init,
BinaryOperation binary_op );
Similarly, according to the general form of the same algorithm, the first two Parameters specify a sequence range, and all elements in this range will be accumulated, but the three parameters indicate the initial value of accumulation. The first version requires that the element itself support addition operations, while the second version also has the fourth parameter. This parameter can be used to pass a function object, which provides the addition operation for two basic elements. Note that the instantiation of the function template is based on the third parameter. Therefore, when the third parameter is passed, we need to be especially careful to make its type consistent with the element types of the first two. The following example shows an error-prone model:
[Cpp]
// V is a vector <double>
Accumulate <v. begin (), v. end (), 0 );
Our intention is to accumulate a double-type container. As a result, 0 instead of 0.0 is passed when the initial value is passed, the accumulate function template is instantiated as an int-type instance, this results in unexpected loss of precision.
The C language has such a function memset, which can be used to continuously fill in values in a memory area. It also provides some similar functions in STL, but they are more abstract and act as containers for objects, instead of the actual physical memory zone. Most of these functions start with fill. It should be noted that some of the filling functions are not safe to use, and the programmer needs to ensure that the container capacity is large enough. For example, the following statements about how to use the fill_n function are insecure:
[Cpp]
Vector <int> vec; // empty vector
// Disaster: attempts to write to 10 (nonexistent) elements in vec
Fill_n (vec. begin (), 10, 0 );
The fill_n function does not help you check whether the specified container has enough space to accommodate these elements, but simply fills in. Therefore, we often use back_inserter to safely Insert elements behind the container.
[Cpp]
Vector <int> vec; // empty vector
// OK: back_inserter creates an insert iterator that adds elements to vec
Fill_n (back_inserter (vec), 10, 0); // appends 10 elements to vec
The back_inserter function template returns an iterator adapter, similar to the container adapter. It encapsulates a container and generates a new object, which can be used as an iterator, every write operation through this iterator implicitly calls the push_back function of the container to insert a new value at the end of the container.
There are three main types of insert iterator adapters. Their write operations correspond to the container operations called as follows:
Back_inserter push_back
Front_inserter push_front
Inserter insert
As mentioned above, the general algorithm for using a common iterator will never change the container size. Therefore, to insert a container, you must use these plug-in iterator adapters.
Next, we will briefly list the declaration forms of common algorithms. For more information about how to use them, see the help documentation.
Remove repeated elements from the container. This function requires that the repeated elements must be continuous:
[Cpp]
Template <class ForwardIterator>
ForwardIterator unique (ForwardIterator first, ForwardIterator last );
Template <class ForwardIterator, class BinaryPredicate>
ForwardIterator unique (ForwardIterator first, ForwardIterator last,
BinaryPredicate pred );
Copy container content:
[Cpp]
Template <class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result );
Replace the specified Element in the container:
[Cpp]
Template <class ForwardIterator, class T>
Void replace (ForwardIterator first, ForwardIterator last, const T & old_value, const T & new_value );
Copy the content to another container and replace the specified Element (this function does not change the original container );
[Cpp]
Template <class InputIterator, class OutputIterator, class T> www.2cto.com
OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T & old_value, const T & new_value );
Calculate the number of elements that meet the condition in the container:
[Cpp]
Template <class InputIterator, class Predicate>
Typename iterator_traits <InputIterator >:: difference_type
Count_if (ForwardIterator first, ForwardIterator last, Predicate pred );
Author: justaipanda