Chapter 21 - Chapter 21 Chapter The STL (maps and...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 21 Chapter The STL (maps and algorithms) Bjarne Stroustrup www.stroustrup.com/Programming Abstract Abstract This talk presents the idea of STL algorithms and This introduces map as an example of a container. introduces Stroustrup/Programming 2 Overview Overview Common tasks and ideals Containers, algorithms, and iterators The simplest algorithm: find() Parameterization of algorithms Sequence containers map, set Standard algorithms vector and list Associative containers find_if() and function objects copy, sort, … Input iterators and output iterators List of useful facilities Headers, algorithms, containers, function objects Stroustrup/Programming 3 Basic model Basic A pair of iterators defines a sequence The beginning (points to the first element – if any) The end (points to the one-beyond-the-last element) begin: end: … An iterator is a type that supports the “iterator operations” of ++ Point to the next element * Get the element == Does this iterator point to the same element as that iterator? Some iterators support more operations (e.g., --, +, and [ ]) Some (e.g Stroustrup/Programming 4 Accumulate (sum the elements of a sequence) (sum template<class In, class T> T accumulate(In first, In last, T init) { while (first!=last) { init = init + *first; ++first; ++first; } v: 1 2 3 4 return init; } int sum = accumulate(v.begin(),v.end(),0); int Stroustrup/Programming // sum becomes 10 becomes 5 Accumulate (sum the elements of a sequence) (sum void f(vector<double>& vd, int* p, int n) { double sum = accumulate(vd.begin(), vd.end(), 0.0); // add the elements of vd double vd // note: the type of the 3rd argument, the initializer, determines the precision used // note: int si = accumulate(p, p+n, 0); // sum the ints in an int (danger of overflow) int in int // p+n means (roughly) &p[n] means long sl = accumulate(p, p+n, long(0)); // sum the ints in a long // sum in double s2 = accumulate(p, p+n, 0.0); // sum the ints in a double // sum in // popular idiom, use the variable you want the result in as the initializer: // popular double ss = 0; ss = accumulate(vd.begin(), vd.end(), ss); // do remember the assignment ss do } Stroustrup/Programming 6 Accumulate Accumulate (generalize: process the elements of a sequence) // we don’t need to use only +, we can use any binary operation (e.g., *) // we // any function that “updates the init value” can be used: init template<class In, class T, class BinOp> T accumulate(In first, In last, T init, BinOp op) { while (first!=last) { init = op(init, *first); // means “init op *first” // means ++first; } return init; } Stroustrup/Programming 7 Accumulate Accumulate // often, we need multiplication rather than addition: // often, Note: multiplies for * #include <numeric> void f(list<double>& ld) { double product = accumulate(ld.begin(), ld.end(), 1.0, multiplies<double>()); // … // } Note: initializer 1.0 // multiplies is a standard library function object for multiplying // is Stroustrup/Programming 8 Accumulate (what if the data is part of a record?) (what struct Record { int units; double unit_price; // … // }; // number of units sold // number // let the “update the init value” function extract data from a Record element: // init element: double price(double v, const Record& r) { return v + r.unit_price * r.units; return } void f(const vector<Record>& vr, map<string,Record*>& m) { double total = accumulate(vr.begin(), vr.end(), 0.0, price); // … // } Stroustrup/Programming 9 Inner product Inner template<class In, class In2, class T> T inner_product(In first, In last, In2 first2, T init) // This is the way we multiply two vectors (yielding a scalar) // This { while(first!=last) { init = init + (*first) * (*first2); // multiply pairs of elements and sum sum ++first; ++first; ++first2; ++first2; number of units 1 2 3 4… } * * * * * return first; unit price 4 3 2 1… } Stroustrup/Programming 10 10 Inner product example Inner // calculate the Dow Jones industrial index: // calculate vector<double> dow_price; // share price for each company // share dow_price.push_back(81.86); dow_price.push_back(81.86); dow_price.push_back(34.69); dow_price.push_back(34.69); dow_price.push_back(54.45); // … // vector<double> dow_weight; // weight in index for each company vector<double> weight dow_weight.push_back(5.8549); dow_weight.push_back (2.4808); dow_weight.push_back(3.8940); // … // double dj_index = inner_product( // multiply (price,weight) pairs and add double multiply dow_price.begin(), dow_price.end(), dow_weight.begin(), 0.0); Stroustrup/Programming 11 Inner product (generalize!) (generalize!) // we can supply our own operations for combining element values with“ init”: // we template<class In, class In2, class T, class BinOp, class BinOp2 > T inner_product(In first, In last, In2 first2, T init, BinOp op, BinOp2 op2) { while(first!=last) { init = op(init, op2(*first, *first2)); ++first; ++first2; } return first; } Stroustrup/Programming 12 Map (an associative array) (an For a vector, you subscript using an integer For vector For a map, you can define the subscript to be (just about) any type For map Key type Value type int main() { map<string,int> words; string s; while (cin>>s) ++words[s]; // keep (word,frequency) pairs // keep // note: words is subscripted by a string // note: is // words[s] returns an int& // returns // the int values are initialized to 0 // the values typedef map<string,int>::const_iterator Iter; for (Iter p = words.begin(); p != words.end(); ++p) cout << p->first << ": " << p->second << "\n"; cout } Stroustrup/Programming 13 An input for the words program (the abstract) This lecture and the next presents the STL (the containers and algorithms part of the C++ standard library). It is an extensible framework dealing with data in a C++ program. First, I present the general ideal, then the fundamental concepts, and finally examples of containers and algorithms. The key notions of sequence and iterator used to tie containers (data) together with algorithms (processing) are presented. Function objects are used to parameterize algorithms with “policies”. algorithms Stroustrup/Programming 14 (data): 1 (processing): 1 (the: 1 C++: 2 First,: 1 Function: 1 I: 1 It: 1 STL: 1 The: 1 This: 1 a: 1 algorithms: 3 algorithms.: 1 an: 1 and: 5 are: 2 concepts,: 1 containers: 3 data: 1 dealing: 1 examples: 1 extensible: 1 finally: 1 framework: 1 fundamental: 1 general: 1 ideal,: 1 in: 1 Output (word frequencies) (word iterator: 1 key: 1 lecture: 1 library).: 1 next: 1 notions: 1 objects: 1 of: 3 parameterize: 1 part: 1 present: 1 presented.: 1 presents: 1 program.: 1 sequence: 1 standard: 1 the: 5 then: 1 tie: 1 to: 2 together: 1 used: 2 with: 3 “policies”.: 1 Stroustrup/Programming 15 Map Map After vector, map is the most useful standard library container After vector map Maps (and/or hash tables) are the backbone of scripting languages Maps A map is really an ordered balanced binary tree map By default ordered by < (less than) By (less For example, map<string,int> fruits; For map<string,int> Map node: fruits: Orange 99 Grape 100 Apple 7 Kiwi 2345 Key first Value second Node* left Node* right … Quince 0 Plum 8 Stroustrup/Programming 16 Map Map Some implementation defined type // note the similarity to vector and list // note list template<class Key, class Value> class map { // … // typedef pair<Key,Value> value_type; // a map deals in (Key,Value) pairs // map typedef ??? iterator; typedef ??? const_iterator; // probably a pointer to a tree node // probably iterator begin(); iterator end(); // points to first element // points // points to one beyond the last element // points Value& operator[ ](const Key&); iterator find(const Key& k); // is there an entry for k? // is void erase(iterator p); // remove element pointed to by p // remove pair<iterator, bool> insert(const value_type&); // insert a new pair before p insert // … // }; Stroustrup/Programming 17 Map example (build some maps) (build map<string,double> dow; // Dow Jones industrial index (symbol,price) , 03/31/2004 // Dow // http://www.djindexes.com/jsp/industrialAverages.jsp?sideMenu=true.html // http://www.djindexes.com/jsp/industrialAverages.jsp?sideMenu=true.html dow["MMM"] = 81.86; MMM"] dow["AA"] = 34.69; dow["AA"] dow["MO"] = 54.45; // … // map<string,double> dow_weight; // dow (symbol,weight) // dow dow_weight.insert(make_pair("MMM", 5.8549)); // just to show that a Map // Map // really does hold pairs // pair dow_weight.insert(make_pair("AA",2.4808)); dow_weight.insert(make_pair("MO",3.8940)); // and to show that notation matters and // … // map<string,string> dow_name; // dow (symbol,name) // dow dow_name["MMM"] = "3M Co."; dow_name["MMM"] dow_name["AA"] = "Alcoa Inc."; dow_name["AA"] dow_name["MO"] = "Altria Group Inc."; Stroustrup/Programming 18 // … // Map example (some uses) (some double alcoa_price = dow["AAA"]; double boeing_price = dow["BO"]; // read values from a map // read if (dow.find("INTC") != dow.end()) cout << "Intel is in the Dow\n"; // look in a map for an entry // look // iterate through a map: // iterate typedef map<string,double>::const_iterator Dow_iterator; for (Dow_iterator p = dow.begin(); p!=dow.end(); ++p) { const string& symbol = p->first; // the "ticker" symbol // the cout << symbol << '\t' << p->second << '\t' << dow_name[symbol] << '\n'; cout } Stroustrup/Programming 19 Map example (calculate the DJ index) (calculate double value_product( const pair<string,double>& a, const pair<string,double>& b) { return a.second * b.second; } // extract values and multiply // extract double dj_index = inner_product(dow.begin(), dow.end(), dow_weight.begin(), 0.0, plus<double>(), value_product ); Stroustrup/Programming // all companies in index // all // their weights // their // initial value // initial // add (as usual) // add // extract values and weights extract // and multiply; then sum // and 20 Containers and “almost containers” Containers Sequence containers Associative containers array, string, stack, queue, priority_queue array, string, Soon-to-become standard containers map, set, multimap, multiset “almost containers” vector, list, deque unordered_map (a hash table), unordered_set, … unordered_map For anything non-trivial, consult documentation Online SGI, RogueWave, Dinkumware Other books Stroustrup: The C++ Programming language (Chapters 16-19,22.6) Austern: Generic Programming and the STL Josuttis: The C++ Standard Library Stroustrup/Programming 21 Algorithms Algorithms An STL-style algorithm Takes one or more sequences Takes one or more operations Usually as pairs of iterators Usually as function objects Ordinary functions also work Usually reports “failure” by returning the end of a Usually sequence sequence Stroustrup/Programming 22 Some useful standard algorithms Some r=find(b,e,v) r=find_if(b,e,p) x=count(b,e,v) x=count_if(b,e,p) sort(b,e) sort(b,e,p) copy(b,e,b2) unique_copy(b,e,b2) merge(b,e,b2,e2,r) r=equal_range(b,e,v) equal(b,e,b2) r points to the first occurrence of v in [b,e) r points to the first element x in [b,e) so that p(x) x is the number of occurrences of v in [b,e) x is the number of elements in [b,e) so that p(x) sort [b,e) using < sort [b,e) using p copy [b,e) to [b2,b2+(e-b)) there had better be enough space after b2 copy [b,e) to [b2,b2+(e-b)) but don’t copy adjacent duplicates merge two sorted sequence [b2,e2) and [b,e) into [r,r+(e-b)+(e2-b2)) r is the subsequence of [b,e) with the value v (basically a binary search for v) does all elements of [b,e) and [b2,b2+(e-b)) compare equal? Stroustrup/Programming 23 Copy example Copy template<class In, class Out> Out copy(In first, In last, Out res) { while (first!=last) *res++ = *first++; // conventional shorthand for: // conventional // *res = *first; ++res; ++first // *res return res; } void f(vector<double>& vd, list<int>& li) { if (vd.size() < li.size()) error("target container too small"); copy(li.begin(), li.end(), vd.begin()); // note: different container types // note: // and different element types // and // (vd better have enough elements // // to hold copies of li’s elements) // li sort(vd.begin(), vd.end()); // … // Stroustrup/Programming } 24 Input and output iterators Input // we can provide iterators for output streams // we ostream_iterator<string> oo(cout); *oo = "Hello, "; ++oo; *oo = "world!\n"; // assigning to *oo is to write to cout // assigning is // meaning cout << "Hello, " // cout // “get ready for next output operation” // “get // meaning cout << "world!\n" // cout // we can provide iterators for input streams: // we istream_iterator<string> ii(cin); istream_iterator<string> string s1 = *ii; ++ii; string s2 = *ii; // reading *ii is to read a string from cin string // meaning cin>>s1 // cin>>s1 // “get ready for the next input operation” // “get // meaning cin>>s2 // cin>>s2 Stroustrup/Programming 25 Make a quick dictionary (using a vector) (using int main() { string from, to; string cin >> from >> to; // get source and target file names get ifstream is(from.c_str()); ofstream os(to.c_str()); ofstream // open input stream open // open output stream // open istream_iterator<string> ii(is); istream_iterator<string> eos; ostream_iterator<string> oo(os,"\n"); ostream_iterator<string> // make input iterator for stream make // input sentinel (defaults to EOF) input // make output iterator for stream // make // append "\n" each time // "\n" // b is a vector initialized from input // is initialized // sort the buffer // sort // copy buffer to output, copy // discard replicated values discard vector<string> b(ii,eos); vector<string> sort(b.begin() ,b.end()); sort(b.begin() unique_copy(b.begin() ,b.end() ,oo); } Stroustrup/Programming 26 An input file (the abstract) (the This lecture and the next presents the STL (the This containers and algorithms part of the C++ standard library). It is an extensible framework dealing with data in a C++ program. First, I present the general ideal, then the fundamental concepts, and finally examples of containers and algorithms. The key notions of sequence and iterator used to tie containers (data) together with algorithms (processing) are presented. Function objects are used to parameterize algorithms with “policies”. algorithms Stroustrup/Programming 27 (data) (processing) (the C++ First, Function I It STL The This a algorithms algorithms. an and are concepts, containers data dealing examples extensible finally Framework fundamental general ideal, Part of the output Part in is iterator key lecture library). next notions objects of parameterize part present presented. presents program. sequence standard the then tie to together used with Stroustrup/Programming “policies”. 28 Make a quick dictionary (using a vector) (using We are doing a lot of work that we don’t really need Why store all the duplicates? (in the vector) Why sort? Why suppress all the duplicates on output? Why not just Put each word in the right place in a dictionary as we read it? In other words: use a set set In Stroustrup/Programming 29 Make a quick dictionary (using a set) (using int main() { string from, to; string cin >> from >> to; // get source and target file names get ifstream is(from.c_str()); ofstream os(to.c_str()); ofstream // make input stream make // make output stream // make istream_iterator<string> ii(is); istream_iterator<string> eos; ostream_iterator<string> oo(os,"\n"); ostream_iterator<string> // make input iterator for stream make // input sentinel (defaults to EOF) input // make output iterator for stream // make // append "\n" each time "\n" // b is a set initialized from input // is initialized // copy buffer to output copy set<string> b(ii,eos); set<string> copy(b.begin() ,b.end() ,oo); } // simple definition: a set is a map with no values, just keys // simple Stroustrup/Programming 30 Set Set A set is really an ordered balanced binary tree set By default ordered by < For example, set<string> fruits; For set<string> set node: Key first fruits: Node* left Node* right … Orange Grape Apple Kiwi Quince Plum Stroustrup/Programming 31 copy_if() copy_if() // a very useful algorithm (missing from the standard library): // very template<class In, class Out, class Pred> Out copy_if(In first, In last, Out res, Pred p) // copy elements that fulfill the predicate // copy { while (first!=last) { if (p(*first)) *res++ = *first; ++first; } return res; } Stroustrup/Programming 32 copy_if() copy_if() template<class T> struct Less_than { // “typical” predicate carrying data // “typical” // this is what you can’t do simply/elegantly with a function // this T val; Less_than(const T& v) :val(v) { } bool operator()(const T& v) const { return v < val; } }; void f(const vector<int>& v) // “typical use” of predicate with data // “typical // copy all elements with a value less than 6 // copy { vector<int> v2(v.size()); copy_if(v.begin(), v.end(), v2.begin(), Less_than<int>(6)); // … // } Stroustrup/Programming 33 Some standard function objects Some From <functional> Binary Unary plus, minus, multiplies, divides, modulus equal_to, not_equal_to, greater, less, greater_equal, less_equal, equal_to, logical_and, logical_or logical_and, negate logical_not Unary (missing, write them yourself) less_than, greater_than, less_than_or_equal, greater_than_or equal Stroustrup/Programming 34 ...
View Full Document

This note was uploaded on 02/18/2012 for the course CSCE 121 taught by Professor Walter daugherity during the Fall '09 term at Texas A&M.

Ask a homework question - tutors are online