C + + generic algorithm (1)

Source: Internet
Author: User

Sequential containers only define very few operations, in order to be able to do more useful things: find specific elements, replace or delete a particular value, rearrange the order of elements, and so on. Generic algorithm is the common interface of some classical algorithms

1. Overview

Most algorithms are defined in the header file algorithm, and the standard library also defines a set of numeric generic algorithms in the header file numeric.

The generic algorithm does not perform the container operation, only runs on top of the iterator and performs the operation of the iterator. This causes the algorithm to not change the size of the container, and it cannot add or remove elements directly. So the standard library defines a special iterator called the insert to complete the effect of adding elements to the container.

2. Initial knowledge of the generic algorithm

The standard library provides more than 100 algorithms.

A. Read-only algorithms

Read only, such as find,count,accumulate,equal. The equal algorithm assumes that the second sequence is at least as long as the first sequence, only three iterators are accepted, the first two represent the range of a sequence, and the third is the first element of the second sequence.

B. Algorithms for writing container elements

With such algorithms, it is important to ensure that the original size of the sequence is at least not less than the number of elements we require the algorithm to write. The algorithm fill accepts a pair of iterators representing a range, accepting a value as the third parameter.

The function Fill_n accepts a single iterator, a count value, and a value. However, you cannot call Fill_n on an empty container, because the algorithm that writes the data to the destination iterator assumes that the destination is large enough to accommodate the element being written.

One way to ensure that the algorithm has enough element space to accommodate the output data is to use an insert iterator. When you use a generic iterator to assign a value to a container element, the value of the element within the container changes. However, when an insert iterator is used to assign a value, an element equal to that value is added to the container.

Inserting an iterator such as Back_inserter, which returns an insert iterator bound to the container, calls Push_back to add an element with the given value to the container, as in the following code, when assigning a value to the insert iterator:

vector<int> vec;//Empty Container

Auto It=back_inserter (VEC);

*it = 42;//vec has an element with a value of 42

Copy algorithm: Accepts three iterators, the first two represent an input range, and the third represents the starting position of the destination sequence. Copy algorithm, the algorithm returns the value of the destination iterator. The Replace algorithm accepts four parameters, the first two are iterators, the third is the value to search for, and the fourth is the new value. The replace_copy algorithm keeps the original sequence intact, just copies a copy of the original sequence and replaces it.

C. Algorithm for rearrangement of container elements

Sort will rearrange the elements to make them orderly. Unique will rearrange the input sequence, move adjacent duplicates to the last face, and return an iterator to the end of the range of distinct values. Erase is used to delete elements.

3. Custom operation

A. For example, sort defaults from small to large, but our requirements may be different, so we need to overload the default behavior of sort. To rearrange the vectors by length, to use the second version of Sort, it accepts the third argument, which is a predicate.

predicate: A predicate is a callable expression whose return result is a value that can be used as a condition. Divided into unary predicate and two-tuple predicate according to the number of parameters

Lambda: We can pass any category of callable objects to an algorithm. So far, two callable objects that have been used are function and function pointers. There are two other callable objects: A class that overloads the function call operator, and a lambda expression.

A lambda expression represents a unit of code that can be called. It can be understood as an unnamed inline function. The form of expression is as follows:

[Capture List] (parameter list), return type {function body}//capture list) is a list of defined local variables, and lambda must return the specified return type using a tail. The capture list and function body must be included.

Lambda Note: A. Cannot have default parameters. B. The capture list captures the local variables of the function it is located in. The procedure is as follows:

Program function: Find the first element with a length greater than or equal to SZ

Auto WC = find_if (Words.begin (), Words.end (), [SZ] (const string &a) {return a.size () >=sz;})

[=,&a,&b] means capturing variables A and B in a reference pass, capturing all other variables by value passing, and capturing the list only for local non-static variables, and lambda can directly use the local static variable and the name declared outside its function. such as cout.

The for_each algorithm accepts a callable object and calls this object on each element of the input sequence.

B.lambda Capture and return

Value capture, since the variable is captured when it is copied at the time the lambda is created, and subsequent modifications to it do not affect the corresponding value within the lambda. Only copy values can be used and cannot be changed. To change, use mutable.

A reference capture that modifies a variable when using this method affects the corresponding value within the lambda.

implicit capture, [=] takes a value capture, [&] takes a reference capture.

Variable lambda: By default, the value of a variable is copied, and the lambda does not change its value. If you want to change, you must add the keyword mutable after the parameter list.

Specify the lambda return type: If a lambda body contains any statements other than return, the compiler assumes that the lambda returns void. In order for a lambda to return a specific type, you need to use the tail return type, and so on.

C. Parameter binding

Lambda expressions are most useful for simple operations that are used only in one or two places. If you want to use the same operation in many places, you should typically define a function.

But the function generally accepts more parameters, but the general algorithm only accepts a unary predicate (a function of a parameter), in order to resolve this contradiction, we use the BIND function.

Auto Newc=bind (c,list);//Convert multiple parameters into one parameter.

Auto Check6 = bind (check_size,_1,6),//Check_size binds two parameters to the function to generate a callable object. To use _1, you need to declare: using std::p laceholders::_1;

Bind parameter: Auto G=bind (f,a,b,_2,c,_1); This uses G (_1,_2), which will be mapped to F (a,b,_2,c,_1);

The binding reference parameter uses the REF function.

4. Re-explore the iterator

Iterator type: A. Insert iterator B. Stream iterator c. Reverse iterator d. Move the iterator.

A. Inserting an iterator

Three types: back_inserter//Create an iterator that uses push_back front_inserter//create an iterator that uses Push_front inserter//create an iterator that uses insert

For example: It=inserter (C,iter);//Get Insert iterator it. *it=val;//add Val before it points to the element

B.iostream iterators

Two types: Istream_iterator reads the input stream and Ostream_iterator writes data to an input stream. Sample program:

Istream_iterator<int> Int_iter (CIN), eof;//read int vector<int> vec (in_iter,eof) from CIN;//Construct VEC

C. Reverse iterator

Crbegin () represents the tail of the container. If R is a reverse iterator, the normal iterator can be obtained by using r.base () for the proper iterator.

5. Generic algorithm structure

(1) Iterator Category: input iterator, output iterator, forward iterator, bidirectional iterator, random-access iterator.

A. Input iterator

Find and accumuluate require an input iterator, while Istream_iterator is an input iterator.

B. Output iterator

The third parameter of copy is an output iterator, and Ostream_iterator is an output iterator.

C. Forward Iterators

Replace requires a forward iterator, and an iterator on the forward_list is a forward iterator.

D. Bidirectional iterator (reverse)

E. Random-access iterators (sort, array, deque, string, vector iterators)

(2) algorithm formal parameter mode

ALG (Beg,end,other args);

ALG (Beg,end,dest,other args);//dest is also an iterator

ALG (Beg,end,beg2,other args);

ALG (Beg,end,beg2,end2,other args);

6. Specific container algorithms

List and Forward_list define the algorithms for several member functions, and they define unique sort,merge,remove,reserse and unique.

The list type also defines the splice algorithm. The unique version of the list of algorithms changes the underlying container, which is the difference from the generic version of the algorithm.

C + + generic algorithm (1)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.