Download presentation
Presentation is loading. Please wait.
Published byFrederick Flynn Modified over 9 years ago
1
CSE 332: C++ STL algorithms C++ STL Algorithms Generic algorithms –Apply to a wide range of types E.g., sorting integers (long) or intervals (long, long) –Don’t require inheritance relationships Types substituted need not have a common base class Need only to be models of the algorithm’s concept Implementations in C++ –Rely on templates, interface-based polymorphism –Algorithms are implemented as function templates –Use types that model iterator concepts –Iterators in turn give access to containers
2
CSE 332: C++ STL algorithms Example: Linear Search From Austern: “Generic Programming and the STL” Sequential (linear) search: find char c in string s char *strchr (char* s, char c) { while (*s != 0 && *s != c) ++s; return *s == c ? s : (char *) 0; } Problem: not very general –“Range” of iteration is always defined up to ‘\0’ character –Only works for a “zero terminated” string in C/C++
3
CSE 332: C++ STL algorithms Linear Search with Ranges First generalization (Austern, pp. 11): use a range char *find1(char* first, char* last, char c){ while (first != last && *first != c) ++first; return first; } Gives an explicit range (calculate its length – how?) Assumes first is before last (can check – how?) Note how caller checks for success changed: why?
4
CSE 332: C++ STL algorithms General Requirements for Linear Search Before we try to improve the algorithm further –Let’s come up with a definition of what it needs to do –This helps to plan what to require and what to leave flexible Any linear search implementation must offer a way to: –Indicate the sequence over which search will occur –Represent a position within the sequence –Advance to the next element of the sequence –Detect the end of the sequence –Return a value as an indication of success or failure Goal: meet these requirements flexibly and efficiently
5
CSE 332: C++ STL algorithms Linear Search over Parameterized Types Second generalization: use templates to parameterize the function argument types template T *find2(T *first, T *last, const T &value){ while (first != last && *first != value) ++first; return first; } How much did the find1 code need to change? One last problem –What if we want to apply this to a data structure whose ranges can’t be traversed via simple pointers?
6
CSE 332: C++ STL algorithms Linear Search with Generic Iterators Third generalization: separate iterator type parameter The STL’s linear search algorithm (Austern pp. 13): template Iterator find(Iterator first, Iterator last, const T& value) { while (first != last && *first != value) ++first; return first; } Our first generic algorithm –Searches any one-dimensional sequence of elements Notice we did not throw an exception –“Not found” is a normal result, not an aberration
7
CSE 332: C++ STL algorithms Algorithm Concepts and Models Remember a concept gives a set of type requirements –Classify/categorize types (e.g., random access iterators) –Tells whether or not a type can or cannot be used with a particular STL algorithm (get a compiler error if it cannot) E.g., we couldn’t use a linked list iterator in find1 or even find2 Any specific type that meets the requirements is a model of that concept –E.g., list ::iterator vs. char * in find Different abstractions (bi-linked list vs. array iterators) No inheritance-based relationship between them But both model iterator concept necessary for find
8
CSE 332: C++ STL algorithms Concepts and Modeling, Continued What very basic concept does the last statement in STL find, ( return first; ) assume? –Asked another way, what must be able to happen to first when it’s returned from function find ? –Same requirement imposed by by-value iterator parameters What other capabilities are required of the Iterator and T type parameters by the STL find algorithm ? template Iterator find (Iterator first, Iterator last, const T & value) { while (first != last && *first != value) ++first; return first; }
9
CSE 332: C++ STL algorithms Matching an Algorithm to the Iterators it Needs == != = == != Comparison ++ -- + - += -= ++ --++ Iteration *p= Write -> [] -> Access =*p Read Random Access BidirectionalForwardInputOutputCategory What STL iterator category does find require?
10
CSE 332: C++ STL algorithms Organization of Algorithms within the STL The header file contains –Non-modifying sequence operations Do some calculation but don’t change sequence itself Examples include count, count_if –Mutating sequence operations Modify the order or values of the sequence elements Examples include copy, random_shuffle –Sorting and related operations Modify the order in which elements appear in a sequence Examples include sort, next_permutation The header file contains –General numeric operations Scalar and matrix algebra, especially used with vector Examples include accumulate, inner_product
11
CSE 332: C++ STL algorithms Example of Using Non-Modifying Algorithms count algorithm –Moves through iterator range –Checks each position for equality –Increases count if equal #include using namespace std; int main (int, char * []) { vector v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(2); int i = 7; cout << i << " appears “ << count(v.begin(), v.end(), i) << " times in v" << endl; i = 2; cout << i << " appears “ << count(v.begin(), v.end(), i) << " times in v" << endl; return 0; } /* output is 7 appears 0 times in v 2 appears 2 times in v */
12
CSE 332: C++ STL algorithms Using a Function Object to Extend an Algorithm count_if algorithm –Generalizes the count algorithm –Instead of comparing for equality to a value –Applies a given predicate function object (functor) –If functor’s result is true, increases count #include using namespace std; template struct odd { bool operator() (T t) const { return (t % 2) != 0; } }; int main (int, char * []) { vector v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(2); cout << "there are " ()) << " odd numbers in v" << endl; return 0; } /* output is there are 2 odd numbers in v */
13
CSE 332: C++ STL algorithms Example of Using Mutating Algorithms copy algorithm –Copies from an input iterator range into an output iterator –Note use of default constructor to get an “off-the-end” (here, “end-of-file”) input iterator –Note use of noskipws (ensure behavior matches expectations) input_file >> noskipws; istream_iterator inF (input_file); ostream_iterator otF (output_file); copy (inF, istream_iterator (), otF); cout << "copied input file: " << input_file_name << endl << " to output file: " << output_file_name << endl; return 0; } /* output: cdgill@hive>./copytest Makefile Makefile2 copied input file: Makefile to output file: Makefile2 cdgill@hive> diff Makefile Makefile2 cdgill@hive> */ #include using namespace std; int main (int argc, char * argv[]) { if (argc != 3) {return 1;} string input_file_name (argv[1]); string output_file_name (argv[2]); ifstream input_file (input_file_name.c_str()); ofstream output_file (output_file_name.c_str());
14
CSE 332: C++ STL algorithms Example of Using Sorting Algorithms sort algorithm –Reorders a given range –Can also plug in a functor to change the ordering function next_permutation algorithm –Generates a specific kind of reordering, called a “permutation” –Can use to generate all possible orders of a given sequence #include using namespace std; int main (int, char * []) { string s = "asdf"; cout << "original: " << s << endl; sort (s.begin(), s.end()); cout << "sorted: " << s << endl; string t(s); cout << "permutations:" << endl; do { next_permutation (s.begin(), s.end()); cout << s << " "; } while (s != t); cout << endl; return 0; } /* output is original: asdf sorted: adfs permutations: adsf afds afsd asdf asfd dafs dasf dfas dfsa dsaf dsfa fads fasd fdas fdsa fsad fsda sadf safd sdaf sdfa sfad sfda adfs */
15
CSE 332: C++ STL algorithms Example of Using Numeric Algorithms accumulate algorithm –Sums up elements in a range (based on a starting sum value) inner_product algorithm –Computes the inner (also known as “dot”) product of two vectors: sum of the products of their respective elements #include using namespace std; int main (int, char * []) { vector v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(2); cout << "v contains "; for (size_t s = 0; s < v.size(); ++s) { cout << v[s] << " "; } cout << endl; cout << "the sum of the elements in v is " << accumulate (v.begin(), v.end(), 0) << endl; cout << "the inner product of v and itself is " << inner_product (v.begin(), v.end(), v.begin(), 0) << endl; return 0; } /* output is: v contains 1 2 3 2 the sum of the elements in v is 8 the inner product of v and itself is 18 */
16
CSE 332: C++ STL algorithms Concluding Remarks STL algorithms give you useful, generic functions –Combine easily with a variety of containers/iterators –Support many common data structure manipulations Finding and modifying values, re-ordering, numeric operations –Reusing them saves you from writing code Many STL algorithms can be extended –Especially by plugging function objects into them –We’ve looked at how to use a few function objects –Next lecture we’ll look at how function objects work You can also create your own generic algorithms –If something you need is not in the STL –Think about the iterator and data type concept it requires –Implement it so it works as generically as possible
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.