Top Banner
STL Algorithms algorithms independent of containers
21

STL Algorithms algorithms independent of containers.

Dec 30, 2015

Download

Documents

Irene Fields
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: STL Algorithms algorithms independent of containers.

STL Algorithms

algorithms independent of containers

Page 2: STL Algorithms algorithms independent of containers.

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

– operate on 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

Page 3: STL Algorithms algorithms independent of containers.

Algorithm Example: find• looks for specific element in range• needs <algorithm>• find(beginRange, endRange, toFind)• returns iterator to first matching element in range of the container

– if associative – not necessarily first, use lower_bound• if not found – returns endRange (past last element)• linear complexity

find() method in map and set is faster (logarithmic), use it instead

find() method in list should be used instead

3

Page 4: STL Algorithms algorithms independent of containers.

find_if with Function Pointer Callback• find_if(beginRange, endRange, condition)• returns iterator to first element in range satisfying condition• third parameter is a callback• may be the name of a function (function pointer)

– need to accept element type– need to be a predicate (return boolean)

• example:

vector<int> vect;

auto it=find_if(vect.begin(), vect.end(), moreThan5);

bool moreThan5(int elem){

return elem>5;

}

4

Page 5: STL Algorithms algorithms independent of containers.

Lambda Expressions• anonymous function

• defined in C++11

• syntax: [capture] -> returnType (parameters){body}• capture – passing discipline and (optionally) name of variables taken from

outside of scope of the lambda expressions– [] no variables defined. Attempting to use any external variables in the

lambda is an error

• clang/gcc apparently still capture external variables, it is not standard– [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 value

• compiler may be able to deduce return type from return statement: returnType is optional

• if no parameters, parentheses are optional

• example: []{cout << ”Hello, World!” << endl;} • can be assigned to function pointer variables

– watch out for implicit captures

• can be used as parameters for other functions, have to conform to signature5

Page 6: STL Algorithms algorithms independent of containers.

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

Page 7: STL Algorithms algorithms independent of containers.

accumulate with various callbacks• accumulates data about container• two forms

accumulate(beginRange, endRange, initialValue) – sums elements, sum initialized to initialValue, returns accumulated value

accumulate(beginRange, endRange, initialValue, callback) invokes callback with two arguments, first is accumulator

• callback can be function or lambda

int product(int num1, int num2){

return num1 * num2;

}

double mult = accumulate(vect.begin(), vect.end(), 1, product);

or

double multLambda = accumulate(vect.begin(), vect.end(), 1,

[](int num1, int num2){return num1 * num2;});

7

Page 8: STL Algorithms algorithms independent of containers.

Function Objects (Functors)• can overload function call operator: operator() in a class

– such class is functor– may have any number of arguments and return any value

• then invoke like a standalone function

class MyFunctor{

public:

MyFunctor(int x) : x_(x) {}

int operator() (int y) {return x_+y;}

private:

int x_;

};

MyFunctor addOne(1); // creating a functor object

cout << addOne(2) << endl; // call it like a regular function

• may keep state between calls. Do not use this feature for algorithms!• for simple tasks lambda functions are preferred

8

Page 9: STL Algorithms algorithms independent of containers.

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• have to be instantiated with type

plus<int> myPlus;

int result = myPlus(3,4);

cut << result << endl;• 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

9

Page 10: STL Algorithms algorithms independent of containers.

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

priority_queue<string, std::vector<string>,std::greater<string>> workWeekR;

• 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 allTrue=accumulate(flags.begin(), flags.end(), true,

std::logical_and<bool>());

10

Page 11: STL Algorithms algorithms independent of containers.

Functor 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

newFunctior bind(oldFunctor, arguments)

where– newFunctor – pointer to new functor with bound parameters– oldFunctor – old functor– arguments – arguments to old functor

• free specified as _1 _2, etc defined in std::placeholders namespace• bound

• auto is useful as return type or it gets complicated• examples

auto f1 = bind(myFunc, _1, str); // binds second parameter to string str

auto f2 = bind(myFunc, _2, _1); // swaps parameters

11

Page 12: STL Algorithms algorithms independent of containers.

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

using namespace std::placeholders;

bool passingScore(int s, int threshold){

return s>=threshold;

}

...

// biding second argument of function passingScore to 70

auto it=find_if(vect.begin(), vect.end(),

bind(passingScore, _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));

• this example is probably easier to read with lambda, how would you implement it?

12

Page 13: STL Algorithms algorithms independent of containers.

Containers of Objects• algorithms perform on non-basic types correctly provided that proper operators are

defined– e.g. operator< for sorting, operator== for searching

• common task: invoke a method on each object– suppose myclass declares myfunc() method and container cont holds

elements of myclass

may be accomplished as follows

for_each(cont.begin(), cont.end(), &myclass::myfunc);– if need to pass parameters, use bind()

for_each(cont.begin, cont.end(), bind(&myclass::myfunc, _1, value));

13

Page 14: STL Algorithms algorithms independent of containers.

Algorithm Categories

• utility – not operating on containers but useful• non-modifying – not updating the container

– search: min_element, max_element, find_fist_of, search, search_n

– comparison: equal, mismatch, liexicographical_compare– operational: for_each– numerical processing: count, count_if, accumulate

• modifying – updating the container• sorting – sorting or (dis)ordering container• set – set functions

14

Page 15: STL Algorithms algorithms independent of containers.

Utility Algorithms• min, max, minmax, swap• operate on a couple of elements• use operator<• use function templates• examples

int x=1,y=2;

cout << min(x, y); // prints1

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

• In C++11, utility algorithms operate on initializer lists: max({1,2,3,4,5});

15

Page 16: STL Algorithms algorithms independent of containers.

Search Algorithms• return iterator to first element found• accept range• by default use opeator== or operator<• find, find_if, find_if_not – already covered• min_element, max_elment – locate element

auto it=min_element(vect.begin(), vect.end());• 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

16

Page 17: STL Algorithms algorithms independent of containers.

Comparison and Operational• comparison – compare entire ranges of elements

equal() – returns true if elements in both ranges are equal

mismatch() returns iterator to the first mismatched element

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.

17

Page 18: STL Algorithms algorithms independent of containers.

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

• 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 by valid state• unique() – eliminates consequent duplicates – useful with sorted

containers

18

Page 19: STL Algorithms algorithms independent of containers.

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

19

Page 20: STL Algorithms algorithms independent of containers.

Sorting• sort() – n log(n) sort of the range• merge() – linear merge of 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()

20

Page 21: STL Algorithms algorithms independent of containers.

Setoperate 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.

21