STL Algorithms algorithms independent of containers STL Algorithms

  • Slides: 27
Download presentation
STL Algorithms algorithms independent of containers

STL Algorithms algorithms independent of containers

STL Algorithms Description • • independent of container types: operate on iterators – operate

STL Algorithms Description • • independent of container types: operate on iterators – operate on the half-open range of elements of a container specified by iterators often behavior can be modified through callbacks – references to code callbacks – function pointers (C-style) – function objects (functors) – lambda expressions (C++11) most algorithms are declared in <algorithm>, some are in <numeric> 2

Algorithm Example: find • • • looks for specific element in range needs <algorithm>

Algorithm Example: find • • • looks for specific element in range needs <algorithm> find(begin. Range, end. Range, to. Find) returns iterator to first matching element in range of the container – if associative – not necessarily first, use lower_bound if not found – returns end. Range (past last element) linear complexity find()function in map and set is faster (logarithmic or constant for hashes), use it instead 3

find_if with Function Pointer Callback • • • find_if(begin. Range, end. Range, condition) returns

find_if with Function Pointer Callback • • • find_if(begin. Range, end. Range, condition) returns iterator to first element in range satisfying condition third parameter is a callback may be the name of a function (function pointer) • function references exist in C++ as well – need to accept element type – need to be a predicate (return boolean) example: vector<int> vect; … auto it=find_if(vect. begin(), vect. end(), more. Than 5); … bool more. Than 5(int elem){ return elem>5; } 4

Lambda Expressions • • anonymous function defined in C++11 syntax: [capture](parameters) -> return. Type

Lambda Expressions • • anonymous function defined in C++11 syntax: [capture](parameters) -> return. Type {body} capture – passing discipline and (optionally) name of variables taken from outside of scope (called context) of the lambda expressions – [] no variables defined. Attempting to use any external variables in the lambda is an error – [x, &y] x is captured by value, y is captured by reference – [&] any external variable is implicitly captured by reference – [=] any external variable is implicitly captured by copy (similar to value) variables are captured at the time of lambda definition (not invocation) if return. Type is omitted and there is a single return statement in body, compiler deduces return type on basis of return-expression if no parameters, parentheses are optional example: []{cout << ”Hello, World!” << endl; } can be used as parameters for other functions, have to conform to signature 5

count_if, generate, for_each • count_if – counts number of elements that satisfy callback condition

count_if, generate, for_each • count_if – counts number of elements that satisfy callback condition int num=55; int cnt = count_if(vect. begin(), vect. end(), [num](int i){return i==num; }); • generate – fills elements with value returned by callback generate(vect. begin(), vect. end(), []{return rand()%10; }); • for_each – executes callback for each element for_each(vect. begin(), vect. end(), [](int i){cout << i << " "; }); 6

accumulate with various callbacks • • accumulates data about container two forms accumulate(begin. Range,

accumulate with various callbacks • • accumulates data about container two forms accumulate(begin. Range, end. Range, initial. Value) – sums elements, sum initialized to initial. Value, returns accumulated value accumulate(begin. Range, end. Range, initial. Value, callback) invokes callback with two arguments, first is accumulator • callback can be function or lambda int product(int num 1, int num 2){ return num 1 * num 2; } double mult = accumulate(vect. begin(), vect. end(), 1, product); or double mult. Lambda = accumulate(vect. begin(), vect. end(), 1, [](int num 1, int num 2){return num 1 * num 2; }); 7

Function Objects (Functors) • • functor – object that may be invoked as a

Function Objects (Functors) • • functor – object that may be invoked as a standalone function done by overloading operator() may have any number of arguments and return any value class My. Functor{ public: My. Functor(int x) : x_(x) {} int operator() (int y) {return x_+y; } private: int x_; }; … • then invoke like a standalone function My. Functor add. One(1); // creating a functor object cout << add. One(2) << endl; // call it like a regular function • may keep state between calls. – use this with caution for algorithms as implementations are free to copy/invoke out of order/invoke concurrently lambdas provide a convenient alternative • 8

generate with Functor class My. Functor{ public: My. Functor(int x) : x_(x) {} int

generate with Functor class My. Functor{ public: My. Functor(int x) : x_(x) {} int operator() () {return x_; } private: int x_; }; … My. Functor add. It(5); vector<int> v(10); generate(v. begin(), v. end(), add. It); what are the resultant values of v? 9

Predefined Functors, Arithmetic • • • STL provides a number of predefined functors defined

Predefined Functors, Arithmetic • • • STL provides a number of predefined functors defined in <functional> in std namespace (need to be imported or scope resolved) arithmetic: plus, minus, multiplies, divides, modulus • may be used in algorithms as callbacks int sum = accumulate(vect. begin(), vect. end(), 0, plus<int>()); • regular operators cannot be used as callbacks, functors are adapters that wrap regular arithmetic operators have to be instantiated with type plus<int> my. Plus; int result = my. Plus(3, 4); cut << result << endl; 10

Comparison and Logical Functors • comparison functors: equal_to not_equal_to less greater less_equal greater_equal –

Comparison and Logical Functors • comparison functors: equal_to not_equal_to less greater less_equal greater_equal – less is used as default comparison in priority_queue container adapter – may be changed, have to specify container, usually vector – example: reversing sorting order in priority_queue<string, std: : vector<string>, std: : greater<string>> work. Week. R; • logical functors: logical_and logical_or logical_not – example: logical_and in accumulate to determine if all boolean elements are true vector<bool> flags; … bool all. True=accumulate(flags. begin(), flags. end(), true, std: : logical_and<bool>()); 11

Function Adapters (Binders) • • binder (function adapter) – a specialized function that creates

Function Adapters (Binders) • • binder (function adapter) – a specialized function that creates a function by assigning (binding) a value of parameter of another function bind() a C++11 feature – most flexible binder new. Function bind(old. Function, arguments) where – new. Functon – pointer to new function with bound parameters – old. Function – old function – arguments to old function, in old-function parameter order • free specified as _1 _2, etc defined in std: : placeholders namespace • • • bound auto is useful as return type or it gets complicated examples auto f 1 = bind(my. Func, _1, str); // binds second parameter to string str auto f 2 = bind(my. Func, _2, _1); // swaps parameters 12

Using Binders to Form Callbacks • binders useful in forming callbacks for algorithims inline

Using Binders to Form Callbacks • binders useful in forming callbacks for algorithims inline using namespace std: : placeholders; bool passing. Score(int s, int threshold){ return s>=threshold; }. . . // biding second argument of function passing. Score to 70 auto it=find_if(vect. begin(), vect. end(), bind(passing. Score, _1, 70)); // binding second argument of standard functor greater_equal auto it = find_if(vect. begin(), vect. end(), bind(std: : greater_equal<int>(), _1, 70)); • last example is probably easier to read with lambda, how would you implement it? 13

std: : function • • • a number of similarly operating constructs: – lambdas

std: : function • • • a number of similarly operating constructs: – lambdas (btw, only non-biding lambdas can be assigned to function pointers) – function pointers – functors – binders std: : function allows to point to any of them, called function objects, uniformly needs functional header signature is in angle brackets examples: // lambda function<void(int)> fp = [](int x){cout << x << endl; }; void func. Reg(int x){ // regular function cout << x << endl; } function<void(int)> fp = func. Reg; 14

Algorithm Categories • • utility – not operating on containers but useful non-modifying –

Algorithm Categories • • utility – not operating on containers but useful non-modifying – not updating the container – search: min_element, max_element, find_first_of, search_n – comparison: equal, mismatch, lexicographical_compare – operational: for_each – numerical processing: count, count_if, accumulate • • • modifying – updating the container sorting – sorting or (dis)ordering container set – set functions 16

Utility Algorithms • • • min, max, minmax, swap • In C++11, utility algorithms

Utility Algorithms • • • min, max, minmax, swap • In C++11, utility algorithms operate on initializer lists: max({1, 2, 3, 4, 5}); operate on a couple of elements use operator< use function templates examples int x=1, y=2; cout << min(x, y); // prints 1 cout << max(x, y); // prints 2 swap(x, y); cout<< x << y; // prints 21 auto pair = minmax(x, y); cout << pair. first << pair. second; // prints 12 17

Non-Modifying Search Algorithms • • • return iterator to first element found accept range

Non-Modifying Search Algorithms • • • return iterator to first element found accept range by default use opeator== or operator< find, find_if_not – already covered min_element, max_elment – locate element auto it=min_element(vect. cbegin(), vect. cend()); adjacent_find – finds the first pair of matching consecutive elements find_first_of – finds first occurrence of elements in target range search – finds target subsequence search_n – finds consecutive elements searches that work on ordered sequences (sorted vector, map, multimap, set, multiset): binary_search, lower_bound, upper_bound, equal_range C++11 functions: find_if_not, minmax_element, all_of, any_of, none_of 18

Non-Modifying Comparison and Operational • • comparison – compare entire ranges of elements equal()

Non-Modifying Comparison and Operational • • comparison – compare entire ranges of elements equal() – returns true if elements in both ranges are equal mismatch() returns a pair of iterators to the first mismatched elements in each range lexicographical_compare() – dictionary order comparison of elements operational for_each() – executes callback on each element of the range: may print a copy of every element, accumulate info about all elements, etc. 19

Modifying Algorithms • • • usually operate on two ranges: source range and destination

Modifying Algorithms • • • usually operate on two ranges: source range and destination (target) range, ranges may be independent, overlapping or the same (in place operation) transform() – similar to for_each() expects callback to return a value to be stored in the target range – variant: has two source ranges, callback accepts two parameters – one for each source range and stores value for the target range. Can be used to process two containers – the target may be one of the source rages copy() – copies source to target range copy_if() – copies if callback returns true C++11 – returns iterator past the last element copied – can be used to trim unused after copy elements replace() – replaces elements with particular value with a different one replace_if() – replaces by new value if callback returns true reverse() – reverses elements in container move() – moving elements with C++11 move semantics, leaves source elements in unspecified but valid state – may move whole container unique() – eliminates consequent duplicates – useful with sorted containers generate_n() – fills elements by invoking callback n times, see later 20

Modifying: Remove (and Erase) • • • remove() – removes elements with specific value

Modifying: Remove (and Erase) • • • remove() – removes elements with specific value remove_if() – removes if callback returns true both modifying algorithms do not erase elements from containers (do not know if whole or full range) – instead move remaining elements forward – return iterator past last remaining elements remove-erase-idiom – get the returned iterator and then use the container’s erase() function to eliminate removed elements – can be done in single line removes are linear – preferred to iterative erase() invocation – for random access containers memory reorganization to keep continuous, results in quadratic complexity 21

Sorting • • • sort() – n log(n) sort of the range merge() –

Sorting • • • sort() – n log(n) sort of the range merge() – linear merge of sorted source ranges – target range has to be large enough – does not return iterator; no elements are removed – number of elements in target container is sum of source sizes: use resize() or erase() to trim target unique() – eliminates duplicates, returns iterator past the last element binary_search() – log(n) search in sorted container for a value, returns true if found – lower_bound() is same complexity but more useful random_shuffle() – reshuffles range in linear time, internally uses rand() 22

Set operate on sorted containers with unique elements, not necessarily sets; in fact, sequential

Set operate on sorted containers with unique elements, not necessarily sets; in fact, sequential containers are recommended • includes() – returns true if first range includes second • set_union() – computes union (duplicates eliminated) from two source ranges, puts it in destination range, returns pointer past last element • set_intersection() – computes intersection of two source ranges • set_difference() – difference (complement) of first range with second – elements of first range that are not present in the second • set_symmetric_difference() – elements of first range that are not present in second and v. v. 23

Enhanced Iterator Functions further enhance the power of algorithms • iterator movement functions –

Enhanced Iterator Functions further enhance the power of algorithms • iterator movement functions – makes iterator operate as random access regardless of type • reverse iterators – iterate in reverse direction • inserters – target range does not have to match source range 24

Iterator Movement Functions poor man’s iterator arithmetic implemented as templates • advance(iterator, position) –

Iterator Movement Functions poor man’s iterator arithmetic implemented as templates • advance(iterator, position) – move iterator, position elements, returns void, iterator needs to be at least input – if iterator is input – moves copy of iterator by repeatedly calling increment – if iterator is random access – calls operator+(position) • next(iterator, position) – returns iterator pointing position elements forward, original iterator is not modified – if iterator is input – repeatedly calls increment – if random access – adds position to iterator • prev(iterator, position) – same as next in reverse direction • distance(first. Iterator, last. Iterator) – returns the number of elements between first. Iterator and last. Iterator. If iterators are random access, uses subtract, otherwise repeatedly calls increment 25

Iterator Adapters: Reverse • declared in <iterator> • reverse_iterator – iterates in reverse order

Iterator Adapters: Reverse • declared in <iterator> • reverse_iterator – iterates in reverse order (increment advances backward) – rbegin() – returns reverse iterator starting at the last element of container – rend() – returns iterator before the first element – base() – returns underlying iterator plus one – useful to determine distance to beginning • crbegin() and crend() also exist 26

Iterator Adapters: Insert • • • insert iterators – special type of output iterators

Iterator Adapters: Insert • • • insert iterators – special type of output iterators designed for algorithms (such as copy_if) to insert rather than overwrite elements do not have to know target range – insert_iterator() • assignment calls insert(position, element)on container, advances insert iterator to the next position • initialized with container, position • inserter(container, position) returns insert_iterator on this position • useful for associative containers whose keys are usually not modifiable on iteration – back_insert_iterator() – calls push_back() on container • back_inserter(container) returns back_insert_iterator for this container – front_insert_iterator() – calls push_front() elements are inserted sequentially, may be inefficient increment/decrement have no effect 27

Algorithms Review • • • what is half-open range? what is a callback? function

Algorithms Review • • • what is half-open range? what is a callback? function pointer? lambda function? what is capture? capture block? capture by reference? capture by copy? • functor? advantages/differences with function pointer? – predefined functors? arithmetic? logical? • binder (function adapter)? binder in a callback? • std: : function purpose/usage? • algorithm categories – utility – non-modifying: search, comparison, operational, numerical processing – modifying – sorting – set • iterator movement functions? • iterator adapters: inserters/reverse? 28