330 likes | 507 Views
CNS 3370. Algorithms. Generic Algorithms. Are all Templates Can process homogeneous sequences of any type arrays, vectors, lists, anything that meets STL requirements (iterators, certain other member functions) There are lots of them!. Algorithms: A First Look. C06/CopyInts.cpp
E N D
CNS 3370 Algorithms
Generic Algorithms • Are all Templates • Can process homogeneous sequences of any type • arrays, vectors, lists, anything that meets STL requirements (iterators, certain other member functions) • There are lots of them!
Algorithms: A First Look • C06/CopyInts.cpp • C06/CopyStrings.cpp • How does copy( ) work?
A First Try at copy( ) template<typename T> void copy(T* begin, T* end, T* dest) { while(begin != end) *dest++ = *begin++;}
A Vector example • vector iterators are not necessarily real pointers • they could be, or not • other containers cannot use pointers as iterators • Their data is not contiguous • But C06/CopyVector.cpp works! • why?
A Second Try at copy( ) • template<typename Iterator>void copy(Iterator begin, Iterator end, Iterator dest) { while(begin != end) *dest++ = *begin++;} • Type deduction the iterator type • Must support !=, ++, and *
Non-mutating Algorithms#include <algorithm> for_each find find_if find_first_of adjacent_find count count_if mismatch equal search find_end search_n
Mutating Algorithms transform copy copy_if copy_backward swap iter_swap swap_ranges replace replace_if replace_copy replace_copy_if fill fill_n generate generate_n remove remove_if remove_copy remove_copy_if unique reverse reverse_copy rotate rotate_copy random_shuffle
Ordering Algorithms Sorting sort stable_sort partial_sort partial_sort_copy nth_element merge inplace_merge partition stable_partition Set Operations includes set_union set_intersection set_difference set_symmetric_difference Heap Operations push_heap pop_heap make_heap sort_heap
Ordering Algorithmscontinued... Searching binary_search lower_bound upper_bound equal_range Min/max min max min_element max_element lexicographical_compare Permutations next_permutation prev_permutation
New C++0x Algorithms • all_of • any_of • none_of • find_if_not • copy_if • copy_n • iota • minmax • minmax_element • partition_copy is_partitioned partition_point • is_sorted is_sorted_until • is_heap • is_heap_until • move • move_backward
A Sort Example(But Don’t do it this way!) • Implements Selection Sort with min_element • also illustrates iter_swap • tests sortedness with adjacent_find • See selsort.cpp
Text Example • Write a program that consults a dictionary for all permutations of a string to find valid words • handy for cheating at Text Twist :-) • See permutations.cpp • uses next_permutation • sorts string first • uses an unordered_set (hash table)
Numeric Algorithms#include <numeric> • accumulate(beg, end, init) • accumulate(beg, end, init, bin_function) • inner_product • partial_sum • adjacent_difference • Will see accumulate later
Predicates • Functions that return a bool • Many algorithms have alternate versions that apply predicates to sequence elements • find_if, count_if, etc. • Examples: • copy_some_ints.cpp • C06/CopyStrings2.cpp • C06/ReplaceStrings.cpp
Stream Iterators • Facilitates reading/writing a sequence from/to a stream • without you doing an explicit loop • ostream_iterator<T>(ostream&, const string& sep) • Examples: C06/CopyInts3.cpp, C06/CopyIntsToFile.cpp • istream_iterator<T>(istream&) • Example: C06/CopyIntsFromFile.cpp
Standard Function Objects#include <functional> Arithmetic plus minus multiplies divides modulus negate Predicates equal_to not_equal_to greater less greater_equal less_equal logical_and logical_or logical_not Reminder: Function objects are types that overload operator( )
A plus Function Object template<class T> struct Plus { T operator()(const T& m, const T& n) { return m+n; } }; int main() { Plus<int> p; cout << p(2,3) << endl; // 5 Plus<string> p2; cout << p2("carrot","top") << endl; // carrottop }
An equal_to Function Object template<class T> struct EqualTo { bool operator()(const T& t1, const T& t2) { return t1 == t2; } }; int main() { EqualTo<int> p; cout << p(2,2) << endl; // 1 EqualTo<string> p2; cout << p2("carrot","top") << endl; // 0 }
Using a Standard Function Object #include <functional> #include <iostream> using namespace std; int main() { greater<int> g; cout << g(3, 4) << endl; // Prints 0 (for false) cout << g(5, 4) << endl; // Prints 1 (for true) }
std::bindA Function Object Adaptor (C++0x Only) • Allows customizing “callables” for use with algorithms (including member functions) • For example, convert a standard binary function object to a unary function object by fixing one of the parameters • bind( ) creates a function object that stores the function and the fixed argument(s) • It overloads operator( ) so you can provide the missing arguments
Using std::bindC++0x Only • bind(fn, arg1, arg2, … argn) • Can provide only some of the args • For missing args, use placeholders • _1 = the first subsequent argument • _2 = the second subsequent argument, etc. • defined in namespace std::placeholders • placeholders can be repeated, ignored, reordered • See copy_some_ints2.cpp
Bind ExampleFix 1starg as 10 int main() { using namespace std::placeholders; auto bf = bind(plus<int>(), 10, _1); // Fix left operand as 10 cout << bf(99) << endl; // Complete the call array<int,5> a = {1,2,3,4,5}; transform(a.begin(), a.end(), a.begin(), bf); copy(a.begin(), a.end(), ostream_iterator<int>(cout, " ")); cout << endl; } /* Output: 109 11 12 13 14 15 */
Bind with Non-static Member Functions • The first parameter is the object: • bind(&Class::memfn,<obj>,parm1,…parmn); • Even the object can be deferred • Works transparently with object pointers • Example: bindmem.cpp • (Note: static member functions work just like stand-alone functions with bind)
Lambda ExpressionsC++0x Only • Anonymous functions • can be created at their point of use • Can be assigned to a variable • Can access surrounding variables • Can be returned from a function • Syntax: • [<capture directives>](<args>){return <expr>} • [<capture directives>](<args>)->type{<body>} • See copy_some_ints3.cpp, sortlambda.cpp
std::functionC++0x Only • A generic type that matches any “callable” • functions, function objects, lambdas with the same call signature • Example: function<int(int,int)> f • int add(int x, int y) {return x+y;}; f = &add; • f = plus<int>(); • f = [] (int x,int y) {return x+y;}; • See function.cpp
Capture Directives • Allow referring to enclosing local and non-local variables in a lambda • Necessary when returning a lambda, since those variables disappear when the outer function returns • Copies are made (reference captures are possible, but useless for lambda returns) • See gtnf.cpp • To capture data members, capture this • see capturethis.cpp • [=]captures all enclosing (by value) on demand
std::accumulate • Computes a sequence’s sum by default • You can change the accumulating operation • By providing an “applicator” function • Takes two args: • the running result • the next value to combine into the result • See accumulate.cpp
A Generic Programming Session • Function “Composition” • c(x) = f1(f2(f3(…fn(x)…))) • Can hold callables in a sequence of std::function • e.g., function<double(double)> • Applies functions backwards • Uses accumulate to form result • Overview on next slide…
From Specialization to Generalization • compose1.cpp (functions of double) • compose2.cpp (functions of T) • compose3.cpp (generalizes sequence type) • compose4.cpp (generalizes the callable type) • Using std::function • compose5.cpp (deduces T) • Using std::function::result_type and std::iterator_traits • compose6.cpp (uses std::accumulate) • compose7.cpp (deduces iterator type) • compose8.cpp (uses a lambda applicator) CNS 3370 - Templates
Finding the .dat files • Windows: • system("dir /b *.dat > datfiles.txt 2>nul"); • UN*X: • system("ls *.dat > datfiles.txt 2>/dev/null"); • system() is defined in <cstdlib> • After processing all the .dat files: • explicitly close your stream, then… • remove("datfiles.txt"); // defined in <cstdio>
Using Modern C++ • Use stream iterators for I/O when feasible • Use copy to copy data • Use range-based functions as applicable • Use transform to negate and smooth data • Use accumulate to compute area • Use a bitset to track ini parameters • Use lambdas when feasible • Other algorithms to consider: • count_if, for_each, max_element