Thinking in C + +: STL algorithm

Posted by Gayner on Tue, 25 Jan 2022 07:28:40 +0100

Thinking in C + + > STL algorithm summary notes.

STL algorithm directory

0. Algorithm overview

  1. fill(), assign value to each element of [first, last].
  2. fill_n(), n elements starting from first are assigned value.
  3. generate(), use the generator to generate a value for each element of [first, last].
  4. generate_n() generates a value for the n elements starting with first.
  5. count(), the number equal to value in the range.
  6. count_if(), the range is the number of decision functions that are true.
  7. copy(), copy the sequence from [first, last) to destination.
  8. copy_backward(), reverse copying elements.
  9. reverse(), inverting the source sequence
  10. reverse_copy(), the source sequence remains unchanged, causing the result to be copied to destination.
  11. swap_ranges(), exchanging contents of two ranges of equal size
  12. rotate(), move the [first, middle) range element to the end of the sequence and [middle, last) to the beginning of the sequence.
  13. rotate_copy() does not change the original sequence, and the rotation result is copied to destination.
  14. next_permutation(), subsequent permutation
  15. prev_permutation(), precursor arrangement
  16. random_shuffle(), rearrange elements (shuffle)
  17. partition(), move the element satisfying the decision function to the beginning of the sequence.
  18. stable_partition(), stable partition, keeping the relative position unchanged
  19. find(), find the position where value first appears
  20. find_if(), find the element that makes the decision function true.
  21. adjacent_find() finds two adjacent equal elements.
  22. find_first_of(), find an element in the second range that is equal to an element in the first range.
  23. search(), find the position where the second sequence first appears in the first sequence.
  24. find_end(), find the position where the second sequence last appears in the first sequence.
  25. search_n(), find a set of count consecutive values in the range.
  26. min_element(), where the minimum value first appears.
  27. max_element(), where the maximum value first appears.
  28. replace(), replace the old value with the new value.
  29. replace_if(), replace the value whose decision function is true with a new value.
  30. replace_copy(), without modifying the original sequence, replace the old value and put it into the result.
  31. replace_copy_if(), without modifying the original sequence, replace the value that makes the decision function true into result.
  32. equal(), judge whether the elements in the two ranges are identical.
  33. lexicographical_compare(), whether the first range is "dictionary order less than" the second range.
  34. mismatch(), where the two ranges do not match.
  35. remove(), delete the element equal to value.
  36. remove_if(), delete the element that makes the decision function true.
  37. remove_copy() does not change the source sequence.
  38. remove_copy_if() does not change the source sequence.
  39. unique(), delete adjacent equal values (copies).
  40. unique_copy() does not change the source sequence.
  41. sort(), sort in ascending order.
  42. stable_sort(), stable ascending sort.
  43. partital_sort(), sort certain elements and put them into [first, middle] in order.
  44. partital_sort_copy() does not change the source sequence.
  45. nth_element(), so that all elements in [first, nth] satisfy the binary decision function.
  46. binary_search(), tells whether value appears in an ordered sequence.
  47. lower_bound(), where value first appears.
  48. upper_bound(), surpassing the last position where value appears.
  49. equal_range(), value the position of the first and last occurrence.
  50. merge(), merge sequences in ascending order.
  51. inplace_merge(), merges two ranges of the same sequence in ascending order.
  52. includes(), judge whether the second range is the first subset of the range.
  53. set_union(), union.
  54. set_intersection().
  55. set_difference(), difference.
  56. set_symmetric_difference(), symmetry difference.
  57. make_heap().
  58. push_heap(), add the element * (last-1) to the [first, last-1) heap and put it in the appropriate position.
  59. pop_heap(), put the largest element * first into position (last-1) and adjust the heap.
  60. sort_heap(), heap sorting, which turns the heap into an ordered sequence and unstable sorting.
  61. for_each(), traverse the operation and discard the return value of the call.
  62. transform(), traverse the operation and keep the return value of the call.
  63. Total().
  64. inner_product(), generalized inner product.
  65. partial_sum(), generalized partial sum.
  66. adjacent_difference(), the difference between adjacent elements.
  67. make_pair(), two objects are encapsulated into one object.
  68. The number of elements between distance(), [first, last().
  69. back_inserter(), iterator.
  70. front_inserter(), iterator.
  71. inserter(), iterator.
  72. min(), smaller value.
  73. max(), the larger value.
  74. swap(), swap a and b.

1. Iterator form:

  1. InputIterator. One allows only a single input iterator to the sequence, and the forward pass uses operator + + and operator *. You can use operator = = and operator= Detect the input iterator, which is the scope of the constraint.
  2. OutputIterator. An output iterator that allows only a single element to be written to the sequence, and the forward pass uses operator + + and operator *. It can hold an unlimited number of objects without end checking. It can be used with ostream (through ostream_iterator), and it is also common to use the iterator type returned by back_insert().
  3. ForwardIterator. Still only use operator + + to move forward, but you can read and write at the same time and judge the equality.
  4. BidirectionalIterator. All operations of ForwardIterator are supported, and operator -- operation is added to support backward movement.
  5. RandomAccessIterator. All operations performed by a regular pointer are supported: you can jump forward and backward by increasing and decreasing an integer value (instead of moving only one element at a time). You can also use operator [] as the subscript index, subtract another iterator from one iterator, or use operator <, operator > to compare the size of the iterator.

2. Filling and generation

These algorithms can automatically fill a range of data with a specific value, or generate a set of values for a specific range.

  • fill: inserts a value into the container multiple times.

    void fill(ForwardIterator first, ForwardIterator last, const T& value);
    void fill_n(OutputIterator first, Size n, const T& value);
    
    • fill() assigns value to each element of [Fitst, last().

    • fill_n() assigns value to n elements starting from first.

  • Generate: use the generator to generate values inserted into the container.

    void generate(ForwardItertor first, ForwardIterator last, Generator gen);
    void generate_n(OutputIterator first, Size n, Generator gen);
    
    • generate() makes a gen() call for each element of [Fitst, last], which can be assumed to produce a different value for each element.

    • generate_n() calls gen() n times and assigns values to n elements starting with first.

3. Counting

All containers contain a member function size(), which tells how many elements the container contains. The return type of size() is the difference of the iterator_ Type (usually ptrdiff_t).

  • count: counts objects that meet certain criteria

    IntegraValue count(InputIterator first, InputIterator last, const EqualityComparable& value);
    
    • count() this algorithm generates the number of elements equal to value in the range of [first, last] (equivalent to operator = =)
    IntegraValue count_if(InputIterator first, InputIterator last, Predicate pred);
    
    • count_ The if () algorithm generates the number of elements within the [first, last] range that can make pred return true.

4. Operation sequence

  • Move sequence (copy):

    OutputIterator copy(InputIterator first, InputIterator last, OutputIteratot destination);
    
    • copy() uses assignment, Copy the sequence from the range [first, last] to the destination, and add the destination after each assignment. It is essentially a "shuffle left" operation, so the source sequence cannot contain the destination sequence. Because of the assignment operation, you cannot directly insert elements into an empty container or the end of the container. You must encapsulate the destination iterator in the insert_iterator (typically use back_inserter() or inserter()).
    BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 destinationEnd);
    
    • copy_backward() is the same as copy, but copies elements in reverse order. It is essentially a "shuffle right" operation. The first target element is destinationEnd-1. The space of the destination sequence range must already exist (assignment is allowed).
  • reverse:

    void reverse(BidirectionalIterator first, BidirectionalIterator last);
    OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator destination);
    
    • reverse() inverts the elements of the source sequence range
    • reverse_copy() keeps the order of the elements in the source sequence range unchanged, copies the inverted elements to the destination, and returns the iterator beyond the last end of the result sequence range.
  • swap:

    ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);
    
    • swap_ranges() exchanges the contents of two ranges of equal size by exchanging the corresponding elements.
  • rotate:

    void rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last);
    OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator destination);
    
    • rotate() moves the content in the [first, middle] range to the end of the sequence, moves the content in the [middle, last) range to the beginning of the sequence, and uses rotate() to perform the change in an appropriate position.
    • rotate_copy() does not change the scope of the original sequence, and copies the rotated elements to the destination, and the returned result exceeds the iterator at the end.
  • permutation:

    Permutation is a unique sort of a group of elements. If there are n elements, there are n! Different element combinations in. These combinations are conceptually sorted in the order of Lexicography (similar to dictionaries), resulting in the concept of previous and next arrangement.

    bool next_permutation(BidirectionalIterator first, BidirectionalIterator last);
    bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering binary_pred);
    bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last);
    bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering binary_pred);
    
    • next_permutation() and prev_permutation() function rearranges the elements into postscript or precursor arrangement, and returns true if successful. If there is no multiple "successor" sorting, the elements are arranged in ascending order, next_permutation() returns false. If there are no multiple precursor sequences, the elements are arranged in descending order, prev_permutation() returns false.
    • The function form with StrictWeakOrdering parameter is binary_pred to perform the comparison, not operator <.
  • shuffle:

    void random_shuffle(RandomAccessIterator first, RandomAccessIterator last);
    void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand);
    
    • random_shuffle this function randomly rearranges the elements in the range. If a random number generator is used, a uniform distribution result is produced. The first form uses the internal random number generator, and the second uses the random number generator provided by the user. For a positive number n, the generator must return a value in the range [0, n).
  • partition:

    BidirectionalIterator partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred);
    BidirectionalIterator stable_partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred);
    
    • These functions move elements that satisfy pred to the beginning of the sequence. The iterator points to the location of its return element, which is the last of these elements (to satisfy the subsequence of pred). This location is called "partition point"
    • Partition () does not specify the order of subsequence elements, stable_ After partition(), the relative position of the elements remains unchanged.

5. Find and replace

These algorithms are used to find one or more objects in a range defined by two iterator parameters.

  • find:

    InputIterator find(InputIterator first, InputIterator last, const EqualityComparable& value);
    
    • The find() algorithm looks for the location where value first appears in [first, last]. If value is not in the range, it returns last. This is a linear search and does not make any assumptions about the sequential path of elements.
    • binary_search() works on an ordered sequence and can find faster.
    InputIterator find_if(InputIterator first, InputIterator last, Predicate pred);
    
    • find_if() performs linear search within the specified range to find an element that meets pred (make predict pred return true). If it cannot be found, it returns last.
    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last);
    ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred);
    
    • adjacent_find() performs a linear search to find two adjacent equal elements. The first form looks for two equal elements (through operator = =). The second way is to find two adjacent elements. When these two elements are found and passed to binary together_ Generate true when PRED. If such a pair is found, the iterator pointing to the first element is returned; otherwise, last is returned.
    ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);
    ForwardIterator1 find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator last2, BinaryPredicate binary_pred);
    
    • find_first_of() performs a linear search within the specified range and finds an element equal to an element in the first range in the second range. The first form uses operator = =, and the second form uses decision function.
    ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);
    ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred);
    
    • The search() algorithm checks whether the second sequence range appears within the range of the first sequence (the order is exactly the same). If so, it returns an iterator pointing to the starting position of the second sequence in the first range sequence. If it is not found, it returns last1. The first form uses operator = =, and the second form detects whether each pair of elements can make binary_pred returns true.
    ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);
    ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate binary_pred);
    
    • find_end() is similar to search(). It looks for whether the sequence of the second range is a subset of the sequence of the first range. search() looks for the position where the subset first appears, and find_end() finds the last occurrence. Returns an iterator that points to the first element of the subset.
    ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value);
    ForwardIterator search_n(ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate binary_pred);
    
    • search_n() looks up a set of count consecutive values in [first, last], which are equal to value (the first form), or returns true (the second form) when passing all these values with the same value to binary_pred. If not found, it returns last.
    ForwardIterator min_element(ForwardIterator first, ForwardIterator last);
    ForwardIterator min_element(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred);
    
    • min_element() returns an iterator pointing to the first occurrence of the "minimum" in the range. If the range is empty, last is returned. The first form uses operator <, and the return value is R (for each element E in the range [first, R, * e < * r is false). The second form uses binary_pred, and the return value is R (for each element E in the range [first, R, * e, * R) is false.
    ForwardIterator max_element(ForwardIterator first, ForwardIterator last);
    ForwardIterator max_element(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred);
    
    • max_element() points to the first occurrence of the maximum value in the range. The first form uses operator <, and the return value is R (for each element E in the range [first, R, * r < * e is false). The second form uses binary_pred, and the return value is R (for each element E in the range [first, R, * e) is false.
  • replace:

    void replace(ForwardIterator first, Forwarditerator last, const T& old_value, const T& new_value);
    void replace_if(ForwardIterator first, Forwarditerator last, Predicate pred, const T& new_value);
    OutputIterator replace_copy(InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value);
    OutputIterator replace_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value);
    
    • Realplace() and replace_copy() finds old_value in [first, last] and replaces it with new_value.
    • replace_if() and replace_copy_if() finds the value satisfying the decision function pred and replaces it.
    • The function in the form of copy does not modify the original range, but assigns the replacement copy to result, and increases result after each assignment.

6. Scope of comparison

The following algorithm provides a way to compare the two ranges.

  • Comparison:

    bool equal(InputIterator first1, InputIterator last1, InputIterator first2);
    bool equal(InputIterator first1, InputIterator last1, InputIterator first2, BinaryPredicate binary_pred);
    
    • In the equal() algorithm, the second range starts from first2 and the length depends on the first range. Returns true if the two ranges are identical (with the same elements and order). The first form uses operator = =, and the second form is binary_pred to determine whether the two elements are the same.
    bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);
    bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinartPredicate binary_pred);
    
    • lexicographical_compare() determines whether the first range is "lexicographically less" than the second range. Returns true if less than. If it is exactly equal and the range 1 is not less than the range 2, false is returned.
    • If the lengths of two ranges are different, in dictionary order, the missing elements in one range play the role of "preceding" the elements in the other range, so "abc" precede s "abcd". If there are no mismatched element pairs at the end of the algorithm, the short range takes the lead. If the first range is a short range, it returns true.
    • Uppercase letters precede lowercase letters.
    • In the first form, operator < performs comparison, and in the second form, binary is used_ pred.
    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
    pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate binary_pred);
    
    • mismatch() indicates where the two scopes begin to differ. In order to complete this work, you must know:

      1. The position of the mismatched element in the first range
      2. The location of the mismatched element in the second range.

      Load the two iterators together into a pair object and return. If there is no mismatch, the return value is the iterator last1 beyond the end combined with the second range. The pair template class contains elements represented by member names first and second, which are defined in < utility >.

7. Delete element:

The STL "delete" function rearranges the sequence, places the "deleted" elements at the end of the sequence, and the "undeleted" elements at the beginning of the sequence, and returns an iterator pointing to the "new end" element of the sequence (the end of the sequence excluding the deleted element).

If new_ If last is the iterator returned by the delete function, the range [first, new_, last] is a sequence that does not contain any deleted elements, while the range [new_, last, last) is a sequence composed of deleted elements.

  • remove:

    ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& value);
    ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, Predicate pred);
    OutputIterator remove_copy(InputIterator first, InputIterator last, OutputIterator result, const T& value);
    OutputIterator remove_copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred);
    
    • Each "delete" here traverses [first, last] from beginning to end, finds the value that meets the deletion criteria, and copies the element that has not been deleted to overwrite the element that has been deleted. The element that has not been deleted maintains the original sorting. It returns the iterator beyond the end, which does not contain any element that has been deleted, and the value of the element pointed to by the iterator is not specified.
    • If version deletion passes each element to the decision function pred() to decide whether to delete (if pred() returns true, delete).
    • The copy version does not change the original sequence, copies the undeleted value to a new range starting from result, and returns an iterator beyond the end pointing to the new range.
  • unique:

    ForwardIterator unique(ForwardIterator first, ForwardIterator last);
    ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred);
    OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result);
    OutputIterator unique_copy(InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred);
    
    • Each unique() algorithm here traverses [first, last], finds adjacent equal values (copies), and deletes the copies by overwriting them. The original order of the elements that have not been deleted remains unchanged. An iterator beyond the end of the range is returned, and the adjacent copies of the range have been deleted.

    • Since only adjacent copies are deleted, sort() is called before unique() to ensure that all copies are deleted.

    • For containing binary_ In the pred call version:

      binary_pred(*i, *(i-1));
      

      If true is returned, * i is considered a copy.

    • The copy version does not change the original sequence, puts the undeleted value into the new range starting from result, and returns the iterator beyond the end of the new range.

8. Sort and calculate the sorted sequence

STL provides a large number of independent sorting algorithms, corresponding to stable, partial or only regular (unstable) sorting. Only partial sorting has copied versions.

There are two versions of each algorithm, including sorting or operation, for the ordered sequence. The first uses the object's own operator < to perform the comparison, and the second uses operator()(a, b) to determine the relative order of a and B.

  • sort:

    Sorting algorithms need random access iterators to limit the range of sequences, such as vector or deque. The list container has its own embedded sort () tree because it only provides two-way iterations.

    void sort(RandomAccessIterator first, RandomAccessIterator last);
    void sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering binary_pred);
    
    • sort() sorts the sequences in the [first, last] range in ascending order. The first uses operator <, and the second uses the provided comparator object to determine the order.
    void stable_sort(RandomAccessIterator first, RandomAccessIterator last);
    void stable_sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering binary_pred);
    
    • stable_sort() performs a stable ascending sort and maintains the original order of equal elements.
    void partital_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last);
    void partital_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, StrictWeakOrdering binary_pred)
    
    • partital_sort() sorts a certain number of elements in the [first, last] range, which can be put into the [first, middle]. At the end of sorting, the remaining elements in the [middle, last] range do not guarantee their order.
    RandomAccessIterator partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last);
    RandomAccessIterator partial_sort_copy(InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, StrictWeakOrdering binary_pred);
    
    • partital_sort_copy() sorts a certain number of elements in [first, last], which can be put into [result_first, result_last] and copied into it. If [first, last] is smaller than [result_first, result_last], fewer elements are used.
    void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);
    void nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, StrictWeakOrdering binary_pred);
    
    • nth_element() is like partital_sort, the elements within the processing (arrangement) range of the part. But more than partital_sort is much less processed. nth_element only guarantees that no matter what location is selected, the location will become a dividing point. All elements in the range [first, nth] will meet the binary decision function in pairs (usually the default is operator <), while all elements in the range (nth, last) do not meet the decision.
    • There is no sort in any range, and partital_ The first range of sort() is ordered.
    • If weak sorting processing (such as median, percentage, etc.) is required, this algorithm is better than partital_sort() is much faster.
  • Ordered sequence lookup:

    If you use these functions in an unordered range, the results are unpredictable.

    bool binary_search(ForwardIterator first, ForwardIterator last, const T& value);
    bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, StricWeakOrdering binary_pred);
    
    • binary_search() tells whether value appears in the sorted range [first, last].
    • Binary lookup uses forward sequential lookup iterators instead of random access iterators because the random access iterator "Yes (is-a)" looks up iterators in forward order. If the iterator passed to one of these algorithms actually supports random access, log time lookup is used, otherwise linear lookup is performed.
    ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value);
    ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value, StricWeakOrdering binary_pred);
    
    • lower_bound() returns an iterator indicating where value first appears in the sorted range [first, last]. If value does not appear, the returned iterator indicates where it should appear in the sequence.
    ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value);
    ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, const T& value, StricWeakOrdering binary_pred);
    
    • upper_bound() returns an iterator indicating that value exceeds the last occurrence of value in the sorted range [first, last]. If value does not appear, the returned iterator indicates where it should appear in the sequence.
    pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, const T& value);
    pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering binary_pred);
    
    • equal_range() essentially combines lower_bound () and upper_bound(), returns a pair indicating the first and last occurrence of value in the sorted range [first, last]. If not found, the two iterators indicate where value should appear in the sequence.
  • merge ordered sequence:

    OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);
    OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering binary_pred);
    
    • merge() copies elements from [first1, last1) and [first2, last2) into the result. The sequence in the result range is sorted in ascending order, which is a stable operation.
    void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last);
    void inplace_merge(BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, StrictWeakOrdering binary_pred);
    
    • inplace_merge() assumes that [first, middle] and [middle, last) are two ranges that have been ordered in the same sequence, and combines the two ranges into a result sequence [first, last] to form an ordered sequence.
  • Set operation:

    Once the ranges are ordered, mathematical set operations can be performed.

    bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);
    bool includes(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, StrictWeakOrdering binary_pred);
    
    • In the include() algorithm, if [first2, last2) is a subset of [First1, last1], return true. No range requires only holding elements completely different from the other range, but if [first2, last2) holds n specific elements, if you want to return true, [first1, last1) must also hold at least n elements at the same time.
    OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);
    OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering binary_pred);
    
    • set_ The Union () algorithm creates the mathematical union of two sorted ranges in the result range, and the return value points to the end of the output range. No one input range requires only elements that are completely different from the other, but if a specific value appears multiple times in two input sets, the result set will contain a larger number of occurrences of exactly the same value.
    OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);
    OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering binary_pred);
    
    • set_ The intersection () algorithm generates the intersection of two input sets in the result, and the return value points to the end of the output range. If a specific value appears more than once in two input sets, the result set will contain a smaller number of occurrences of exactly the same value.
    OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);
    OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering binary_pred);
    
    • set_ The difference () algorithm produces a mathematical set of differences, and the return value points to the end of the output result range. All elements that appear in [first1, last1), but not in [first2, last2), are placed in the result set. If a specific value appears multiple times in two input sets (n times in set 1 and m times in set 2), the result set will contain max (n-m, 0) copies of this value.
    OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);
    OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering binary_pred);
    
    • set_ symmetric_ The result set of the difference () algorithm consists of:

      1. All elements in set 1 but not in set 2.
      2. All elements in set 2 but not in set 1.

      If a specific value appears multiple times in two input sets (n times in set 1 and m times in set 2), the result set will contain abs (n-m) copies of this value, where abs () is a function taking the absolute value. The return value points to the end of the output result range.

9. Heap operation

The heap operation in the standard library allows a sequence to be regarded as a "heap" data structure, which can efficiently return the elements with the highest priority without sorting the whole sequence.

Priority is determined by some comparison functions. The first version performs comparison through operator < and the second version uses the operator()(a, b) of the StrictWeakOrdering object to compare two objects: a < B.

  • heap:

    void make_heap(RandomAccessIterator first, RandomAccessIterator last);
    void make_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering binary_pred);
    
    • make_ The heap () algorithm transforms an arbitrary sequence range into a heap.
    void push_heap(RandomAccessIterator first, RandomAccessIterator last);
    void push_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering binary_pred);
    
    • push_ The heap() algorithm adds an element * (last-1) to the heap determined by the range [first, last-1). The last element is placed in a suitable position in the heap.
    void pop_heap(RandomAccessIterator first, RandomAccessIterator last);
    void pop_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering binary_pred);
    
    • pop_ The heap () algorithm puts the largest element * first in position * (last-1) and reorganizes the remaining range to maintain the heap structure. If only * first is taken, the next element will not be the next largest element, so pop must be called to maintain the heap_ Heap() completes the operation.
    void sort_heap(RandomAccessIterator first, RandomAccessIterator last);
    void sort_heap(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering binary_pred);
    
    • sort_heap() algorithm transforms a sequence arranged in heap order into ordinary order, so that it is no longer a heap. Unstable sorting.
    • Call sort_ After heap (), push cannot be called within the scope of this sequence_ Heap () or pop_heap().

10. Calculate all elements in a certain range

These algorithms traverse the entire range and perform operations on each element.

  • Traversal operation:

    UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFuction f);
    
    • for_each() algorithm applies the function object f to each element in [first, last], discarding the return value of F. if f is only a function pointer, it has nothing to do with the return value; if f is an object that retains some internal state, the object can capture a return value, which can be combined and applied to the range. The final return value is f.
    OutputIterator transform(InputIterator first, InputIterator last, OutputIterator result, UnaryFunction f);
    OutputIterator transform(InputIterator1 first, InputIterator1 last, InputIterator2 first2, OutputIterator result, BinaryFunction f);
    
    • transform() applies the function object f to each element in the range [first, last]. However, it does not discard the call result. transform() copies the result (operator =) to * result, and increases the content of the result after each copy. (the sequence pointed to by the result must have enough space; otherwise, an inserter is used to force insertion instead of assignment.)
    • The first form calls f(*first), and the second form calls f(*first1, *first2). The return value is an iterator beyond the end, which indicates the range of the result output.

11. Numerical algorithm

These algorithms are included in the header file < numeric > and are mainly used to perform numerical calculations.

  • total:

    T accumulate(InputIterator first, InputIterator last, T result);
    T accumulate(InputIterator first, InputIterator last, T result, BinaryFunction f);
    
    • The first form of accumulate() is generalized summation, which executes result=result+*i for each element of [first, last] pointed to by iterator i, and result is of type T.
    • The second form applies the function f(result, *i) to each element * i in the range.
  • Inner product:

    T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
    T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryFunction1 op1, BinaryFunction2 op2);
    
    • inner_ The product() algorithm computes a generalized inner product of the ranges [first1, last1) and [first2, first2 + (last1-first1)). The element in the first sequence is multiplied by the "parallel" element in the second sequence and the product is added to produce the return value.

    • The parameter init is the initialization value of the inner product, which may be 0 or any value.

    • The second sequence contains at least as many elements as the first sequence.

    • The second form applies a pair of functions to the sequence. Function op1 replaces addition and function op2 replaces multiplication.

      Sequences {1, 1, 2, 2} and {1, 2, 3, 4}, the inner product is

      ( 1 ∗ 1 ) + ( 1 ∗ 2 ) + ( 2 ∗ 3 ) + ( 2 ∗ 4 ) (1*1)+(1*2)+(2*3)+(2*4) (1∗1)+(1∗2)+(2∗3)+(2∗4)

      The second version indicates that the following operations will be performed:

      init = op1(init, op2(1,1));
      init = op1(init, op2(1,2));
      init = op1(init, op2(2,3));
      init = op1(init, op2(2,4));
      
  • Generalized partial sum:

    OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result);
    OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryFunction op);
    
    • partial_sum() computes a generalized partial sum. Create a new sequence starting with result. Each element in the new sequence is the cumulative sum from the first element to the currently selected element in the [first, last] range.

      Sequence {1, 1, 2, 2, 3},

      The output is {1, 1 + 1, 1 + 1 + 2, 1 + 1 + 2 + 2, 1 + 1 + 2 + 2 + 3} = {1, 2, 4, 6, 9}.

    • The second version uses the binary function op instead of the + operator to obtain all the "totals" accumulated to that point and combine them with the new values.

      Use multiples < int > () (a kind of multiplication op) as the object for {1, 1, 2, 2, 3},

      The output is {1, 1, 2, 4, 12}

    • The return value points to the end of the output range [result, result + (last first)).

  • Difference between adjacent elements:

    OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);
    OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryFunction op);
    
    • adjacent_ The difference () algorithm calculates the difference between adjacent elements in [first, last]. This means that in the new sequence, the value of each element is the difference between the current element and the previous element in the original sequence (the first value remains unchanged).

      Sequence {1, 1, 2, 2, 3}

      Output {1, 1-1, 2-1, 2-2, 3-2} = {1, 0, 1, 0, 1}

    • The second form uses the binary function op instead of the '-' operator to perform "subtraction".

      For example, use multiplies < int > () (multiplication instead of subtraction)

      Output {1, 1, 2, 4, 6}

    • The return value points to the end of the output range [result, result + (last first)).

12. Basic tools

Some basic tools used with other algorithms.

  • pair:

    (templates in the <utility> header)
    template<class T1, class T2> struct pair;
    template<class T1, class T2> 
    pair<T1, T2> make_pair(const T1&, const T2&);
    
    • pair is a simple way to encapsulate two objects into one object.
    • You can directly insert() a pair into a map or multimap. For these containers, pair is value_type.
  • Number of elements:

    (From <iterator>)
    difference_type distance(InputIterator first, InputIterator last);
    
    • The distance() algorithm calculates the number of elements between [first, last], and returns an integer indicating the number of times that must be increased before first equals last. This process does not resolve the iterator.
  • Create iterator:

    (From <iterator>)
    back_insert_iterator<Container> back_inserter(Container& x);
    front_insert_iterator<Container> front_inserter(Container& x);
    insert_iterator<Container> inserter(Container& x, Iterator i);
    
    • back_inserter(),front_inserter() and inserter () are used to create iterators for a given container to insert elements into the container instead of overwriting existing elements in the container with operator = (the default behavior).
    • Each type of iterator has a different insertion operation. back_ insert_ The iterator uses push_back(),front_ insert_ The iterator uses push_front(),insert_ The iterator uses insert().
  • Smaller value:

    const LessThanComparable& min(const LessThanComparable& a, const LessThanComparable& b);
    const T& min(const T& a, const T& b, BinaryPredicate binary_pred);
    
    • The min() algorithm returns the smaller of the two parameters. If they are equal, it returns the first parameter.
    • The first version executes operator <, and the second version passes parameters to binary_pred performs a comparison.
  • Larger value:

    const LessThanComparable& max(const LessThanComparable& a, const LessThanComparable& b);
    const T& max(const T& a, const T& b, BinaryPredicate binary_pred);
    
    • max() returns the larger of the two parameters.
  • Exchange:

    void swap(Assignable& a, Assignable& b);
    void iter_swap(ForwardIterator1 a, ForwardIterator2 b);
    
    • swap() and iter_swap() uses the assignment method to exchange the values of a and b.
    • All containers have a specialized version of swap (), which is more efficient.

Topics: C++ Algorithm data structure STL