Container Algorithm
<algorithm>
bec++
Self-contained container algorithms that provide a range of useful algorithms. When talking about container algorithms, we will most likely use the predicatepredicate
The type returned by the predicate is boolean(bool)
can belambda
Expressions, function objects, and other callable objects.
find
-
find()
Find Elementsfind
accepts three parameters, the third of which is the value type.set
、map
bring one's owncount
The function also accomplishes this, returning the value0
Indicates that it does not exist. For the convenience of this concatenationfind_if
、find_if_not
、find_first_of
、find_end
cap (a poem)adjacent_find
Give examples together.vector<int> a{1, 1, 2, 3, 4, 4, 5}; vector<int> b{5, 6, 6}; find((), (), 3); // Returns an iterator, returns () if not found find_if((), (), [](auto x){return x ! = 3;}); // accepts a unary predicate, find the first element that satisfies the condition find_if_not((), (), [](auto x){return x ! = 3;}); // Accept a unary predicate and find the first element that does not satisfy the condition // find_first_of finds the first element of the second range that exists in the first range (and may not be the first element of the second range) returns the iterator, which also supports a binary predicate. vector<int> a{1, 1, 2, 3, 4, 4, 5}. vector<int> b{6, 5, 6}; auto it = find_first_of((), (), (), (), ()); cout << *it << endl; // return 5 // find_end finds the position of the last matching subsequence, returns the iterator at the beginning of the last subsequence, also supports a binary predicate vector<int> a{1, 1, 2, 3, 1, 4, 1, 2}; vector<int> b{1, 2}; auto it = find_end((), (), (), (), ()); cout << distance((), it) << endl; // 6 points to 7th element // adjcent_find finds two elements that are neighbors of a value, returns an iterator pointing to the first element found, accepts a binary predicate vector<int> a{1, 1, 2, 3, 4, 1, 2}; vector<int> b{1, 2}. auto it = adjacent_find((), ()); auto it = adjacent_find((), (), [](auto a, auto b)->bool{return a + b = 10; }); cout << *it << endl;
de-emphasize
-
unique((), ())
Remove consecutive identical valuesunique
The purpose of the function is to remove consecutive identical values, unique also supports passing in binary predicates (which can be interpreted as functions with one argument), which return an iteratorit
But it's not.end()
, with unspecified values in the middle (access may result in undefined behavior). Be careful not to useset
cap (a poem)map
, what is returned are constants iterators cannot be changed, i.e. the elements they point to cannot be changed.// Write without predicates vector<int> a{1, 1, 2, 3, 4, 4, 5}; auto it = unique((), ()); // at this point a is {1, 2, 3, 4, 5} for_each((), (), [](auto it){cout << it << endl;}); // Output is {1, 2, 3, 4, 5, 4, 5} for_each((), it, [](auto it){cout << it << endl;}); // output is {1, 2, 3, 4, 5} // with binary predicates vector<int> a{1, 1, 2, 3, 4, 4, 5}; // output is {1, 2, 3, 4, 5}. auto it = unique((), (), (), [] a (), [](auto a, auto b) -> bool{return a ! = b;}); // At this point a is {1, 2, 3, 4, 5}, and the lambda expression acts as a binary predicate, taking two serious from the array at a time for judgment, and then removing the unequal elements. for_each((), (), [](auto it) -> int{cout << it << endl;}); // Error, this is because unique removes the value pointed to by the returned iterator to the subsequent end() iterator, but the space remains. Accessed at this point, undefined behavior occurs. for_each((), it, [](auto xs){cout << xs << endl;}); // 1, 1 cout << distance((), ()) << endl; // 7, distance seeks distance is 7
-
unique_copy()
Remove consecutive identical values and copy to target containerNote that you allocate space before using this function, and then use the
unique_copy
There is no memory allocation, just an assignment to another container, which results in undefined behavior if the unassigned portion of the container region is accessed. Similarly, binary predicates are supported, which determine the removal of consecutive values by binary predicates.vector<int> a{1, 1, 2, 3, 4, 4, 5}; vector<int> b(7, 0); auto it = unique_copy((), (), ()); for_each((), it, [](auto xs){cout << xs << endl;}); // out: 1 2 3 4 5 // Binary predicates, instead of using binary predicates to compare numbers directly, you can use remove to do so auto it = unique_copy((), (), (), [x], [x], [x], [x]) (), (), [x](auto a, auto b) -> bool{return a == 3;}). for_each((), it, [](auto xs){cout << xs << endl;}); // out: 1 1 2 3, interpreted values equal to 3 to do unique_copy auto it = unique_copy((), (), [), [), [), [) (), (), [x](auto a, auto b) -> bool{return a == b;}). for_each((), it, [](auto xs){cout << xs << endl;}); // out: 1 2 3 4 5, explaining a = b before copying
arrange in order
-
sort()
Sorting containerssort
For sorting container elements, sort also accepts the binary predicatesort((), ()); sort((), (), greater<>()); // use the greater\less object that comes with the library
Iterator Difference
-
distance()
Find the distance between iterationsdistance
Used to calculate the difference between two iterators, only used for the same container, theset
,map
,vector
It all works.distance((), ());
Iteration Container
-
for_each()
respond in singingfor_each_n
Iterates over each element of the container and performs the operation specified by the function, with the third argument being a function. If the element pointed to by the iterator is to be modified, theset
It just won't work becauseset
Returns a constant iterator.array<int, 5> a{1, 2, 3, 4, 5}; for_each((), (), [](int& x){cout<< x; x; x *= 2;}); // At this point the element values change because the capture is by reference. for_each((), (), [](auto x) -> void{x *= 2; cout << x;}); // At this point the element value will not change, the capture is a value and will become a copy. for_each_n(, 5, [](auto x) -> void{x *= 2; cout << x;}); // The second argument specifies the number of operations, n, to be performed on n elements.
Copy element
-
copy()
Ability to copy elements from the container after the output iteratorout iterator
vector<vector<int>> sx(1); // It is recommended to allocate multiple spaces before copying to avoid unnecessary expansion copy((), () , ()); // You can copy the elements between [begin, end) to the position from begin(). This operation overwrites the original elements once // An interesting approach is to use back_inserter to indicate that you want to do end-insertion. Some containers that support two-way insertion can also be transformed into untailed containers, eliminating some of the hassle of having to choose an insertion function. // set, map class red-black tree containers do not have a back_inserter method, and cannot make such calls, note that copy((), () , back_inserter(sx)); // Negative values will insert elements at the end. vector<int> a{1, 2, 3}. vector<int> a{1, 2, 3}; set<int> s. copy((), () , back_inserter(s)); // Error // Next we consider a copy to vector<vector<int>> vector<vector<int>> v(1); // At this point, the capacity of the external vector is 1, and size is also 1. This means that there exists an internal vector container element, but at this point, vector[0] has a size and capacity of 0, and is an empty container. copy((), (), back_inserter(v)); // At this point the internal empty container is 2
-
copy_backward()
Ability to copy elements from the container before the output iterator.map、set
class is also not supported. This container algorithm overwrites the elements before the output iteratorvector<int> a{1, 2, 3, 4, 5, 6}; set<int> s. copy_backward((), () , s); // Error copy_backward((), () + 3, ()); // OK a{1, 2, 3, 1, 2, 3} copy_backward((), () + 3, ()); // OK, but the array won't change in any way, which is equivalent to copying until the begin() iterator makes no sense.
permutation (i.e. ordered choice of n elements out of a list)
next_permutation
Provides a full permutation of the return container and also supports a binary predicate.
next_permutation((), ());
set (math.)
set_intersection
Take the intersection,set_union
Fetch and set,set_difference
Taking a one-sided difference set, theset_symmetric_difference
Taking the difference set on both sides, it is worth noting that theset_difference
Only the elements in the first container will be output in the output to the result container (regardless of whether the elements in the first container are less than the elements in the second container). All four functions accept a binary predicate. Attention:map
cap (a poem)set
None of them can be used because the underlying implementations of all three functions require the use of the self-incrementing operator, whereas map and set only have constant iterators that do not support such operations. Application Scenario:vector
etc. containers.
vector<int> a{1, 2, 2, 6, 7, 9};
vector<int> b{1, 2, 5, 8, 10};
vector<int> interResult;
vector<int> unionResult;
vector<int> differenceResult;
vector<int> symmetricResult;
set_intersection((), (),(), (), back_inserter(interResult));
set_union((), (),(), (), back_inserter(unionResult));
set_difference((), (),(), (), back_inserter(differenceResult));
set_symmetric_difference((), (),(), (), back_inserter(symmetricResult));
cout << "intersection:" <<endl;
for_each((), (), [](auto& item){cout << item << ":";});
cout << endl;
cout << "differencesection:" <<endl;
for_each((), (), [](auto& item){cout << item << ":";});
cout << endl;
cout << "unionsection:" <<endl;
for_each((), (), [](auto& item){cout << item << ":";});
cout << endl;
cout << "symmetric_diff_section:" <<endl;
for_each((), (), [](auto& item){cout << item << ":";});
/* output
* intersection:
* 1:2:
* differencesection:
* 2:6:7:9:
* unionsection:
* 1:2:2:5:6:7:8:9:10:
* symmetric_diff_section:
* 2:6:7:9:5:8:10 */
look for sth.
search
searching for subsequences in the string.search_n
Search for a fixed number of consecutively repeated values in the string.search_n
accepts a binary predicate, and both functions are capable of using theset
cap (a poem)map
。search
Accepting asearcher
Callable objects, butsearch_n
insofar asset
is meaningless becauseset
There are no duplicate values in the
vector<int> a{1,1,1,4};
vector<int> b{1,2};
auto it = search((), (),(), ());
auto xs = search_n((), (), 3, 1);
int ret = it == ()? -1 : 1;
int res = xs == ()? -1 : 1;
cout << ret <<endl; // -1; not found
cout << res << endl; // 1; Got it.{1,1,1}