Location>code7788 >text

C++ Container Algorithm

Popularity:879 ℃/2024-08-28 00:41:19

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 predicatepredicateThe type returned by the predicate is boolean(bool)can belambdaExpressions, function objects, and other callable objects.

find

  1. find()Find Elements

    findaccepts three parameters, the third of which is the value type.setmapbring one's owncountThe function also accomplishes this, returning the value0Indicates that it does not exist. For the convenience of this concatenationfind_iffind_if_notfind_first_offind_endcap (a poem)adjacent_findGive 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

  1. unique((), ())Remove consecutive identical values

    uniqueThe 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 iteratoritBut it's not.end(), with unspecified values in the middle (access may result in undefined behavior). Be careful not to usesetcap (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
    
  2. unique_copy()Remove consecutive identical values and copy to target container

    Note that you allocate space before using this function, and then use theunique_copyThere 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

  1. sort()Sorting containers

    sortFor sorting container elements, sort also accepts the binary predicate

    sort((), ());
    sort((), (), greater<>()); // use the greater\less object that comes with the library
    

Iterator Difference

  1. distance()Find the distance between iterations

    distanceUsed to calculate the difference between two iterators, only used for the same container, thesetmapvectorIt all works.

    distance((), ());
    

Iteration Container

  1. for_each()respond in singingfor_each_nIterates 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, thesetIt just won't work becausesetReturns 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

  1. 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
    
  2. copy_backward()Ability to copy elements from the container before the output iterator.

    map、setclass is also not supported. This container algorithm overwrites the elements before the output iterator

    vector<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_permutationProvides a full permutation of the return container and also supports a binary predicate.

next_permutation((), ());

set (math.)

set_intersectionTake the intersection,set_unionFetch and set,set_differenceTaking a one-sided difference set, theset_symmetric_differenceTaking the difference set on both sides, it is worth noting that theset_differenceOnly 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:mapcap (a poem)setNone 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:vectoretc. 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.

searchsearching for subsequences in the string.search_nSearch for a fixed number of consecutively repeated values in the string.search_naccepts a binary predicate, and both functions are capable of using thesetcap (a poem)mapsearchAccepting asearcherCallable objects, butsearch_ninsofar assetis meaningless becausesetThere 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}