Upload
lamquynh
View
232
Download
1
Embed Size (px)
Citation preview
C++ for C Programmers by Ira Pohl
C++ 2011 Standard
l C++ For C Programmers :2nd half l C++11 feature of the day l STL
C++ for C Programmers by Ira Pohl
Part I
l You have completed Part I, and:
l Know basic C++
l Have coded both Min Spanning Tree and Dijkstra’s algorithm
l Followed in my book – if available Ch1-6
C++ for C Programmers by Ira Pohl
Part II
l More Standard Template Library
l New features of C++11, such as move semantics, and lambda expressions
l AI techniques used in implementing the game of Hex
l Highlight
C++ for C Programmers by Ira Pohl
New in C++11 std
l Let us introduce new practice and see how it replaces existing practice
l enum class is a type safe better form of enumeration type
C++ for C Programmers by Ira Pohl
Example :enum class
l enum class Color{RED, GREEN, BLUE}; l enum class Stoplight{RED, YELLOW, GREEN};
l With simple enums these shared enumerators would be ambiguous
l In C++11 they constitute separate type Stoplight::RED is different in type from Color::RED; both can be used in the same scope
C++ for C Programmers by Ira Pohl
enum class enumerator type
l The underlying type of enum classes is by default an int; this can be specified to be a different integral type .
l enum class Color : short {RED, BLUE, GREEN};
l enum class Identifier : Integral_Type{ enumerator list};
C++ for C Programmers by Ira Pohl
Quiz: Define an enumerator
l Define a enum class that models three logical values – yes, no, maybe- whose underlying type is unsigned and where yes>maybe>no
l --- also yes worth 2 maybe’s
C++ for C Programmers by Ira Pohl
Answer
l enum class WierdLogic :unsigned{ l NO, l MAYBE = 5, l YES = 10 l }; // a yes is worth 2 maybe’s
C++ for C Programmers by Ira Pohl
Standard Template Library
l Three Legged Stool l Containers: Sequence containers
l vector, deques, list l Associative containers
l set,map l Iterators: input …random l Algorithms:
l Non-mutating sequence algorithms : Find, Count l Mutating Sequence: Copy Random Shuffle, l Sorting-Related:sort, Merge l Numeric: accumulate, inner product
C++ for C Programmers by Ira Pohl
Some New Libraries C++11
l <regex> - regular expression l <thread> - threading l <unordered_map> -hash based map l <array> - fixed size array l <forward_list> - singly linked list l And much more …
C++ for C Programmers by Ira Pohl
Quiz:
l In C
l A C container is ? l A C iterator is ? l A C algorithm is ? l Generics can be done clumsily with?
C++ for C Programmers by Ira Pohl
Answers:
l In C
l A C container is an array such as l int d[100] l A C iterator is a pointer int* p = d; l A C algorithm is ? rand(), sqrt() … l Generics can be done clumsily with void*
C++ for C Programmers by Ira Pohl
Iterator Categories
l We have seen input and output iterators l Must have a single pass algorithm such as find
l Next up forward, bidirectional, random access
C++ for C Programmers by Ira Pohl
C++ Forward Iterator
l Search forward direction one-by-one. l The operator ++ is defined ("advance
the iterator") and dereferencing operators * and ->.
l Iterators may be compared for equality == and != and may be constructed and copy constructed. A canonical algorithm using this iterator is the STL replace algorithm:
C++ for C Programmers by Ira Pohl
replace
l template<class T> void replace(ForwardIterator first, ForwardIterator last,
const T& x, const T& y);
l This algorithm replaces occurences of x by y in the specified iterator range.
C++ for C Programmers by Ira Pohl
Square using iterator
l #include<iostream> #include<iterator> #include<fstream> #include<vector> using namespace std; template<typename ForwardIterator> void square(ForwardIterator first, ForwardIterator last) { for(; first!=last; first++) *first = (*first) * (*first); }
C++ for C Programmers by Ira Pohl
main
l int main() { ….
square(w.begin(), w.end());
for(auto i: w) // range for
cout << i << "\t"; cout << endl; }
C++ for C Programmers by Ira Pohl
Example: Poker Probability
l Wish to compute the probability in 5 card stud of making a straight flush
l Will create abstract data types to have card l Will use vector and shuffle from STL
C++ for C Programmers by Ira Pohl
Quiz:
l Poker probabilities for 5 card stud
l Flush is approximately l A) 1/10, B)1/500 , C) 1/10,000
l Straight Flush is approximately l A) 1/700, B)1/7000, C)1/70,000
C++ for C Programmers by Ira Pohl
Some types
l enum class: short suit{SPADE, HEART, DIAMOND, CLUB};
l class pips{ l public: l pips(int val):v(val){ assert(v>0 && v <14);} l friend ostream& operator<<(ostream& out, pips p); l int get_pips(){return v;} l private: l int v; l };
C++ for C Programmers by Ira Pohl
Card type
l class card l { l public: l card():s(suit::SPADE),v(1){} l card(suit s, pips v):s(s),v(v){} l friend ostream& operator<<(ostream& out, card c ); l suit get_suit(){return s;} l pips get_pips(){return v;} l private: l suit s; l pips v; l }; l ostream& operator<<(ostream& out, card c ){ l cout << c.v << c.s; //presumes << overloaded for pips and suit l return out; l }
C++ for C Programmers by Ira Pohl
Deck – vector of cards
l void init_deck(vector <card> & d){ l for(int i = 1; i < 14; ++i){ l card c(suit::SPADE, i); l d[i-1] = c; l } l for(int i = 1; i < 14; ++i){ l card c( suit:: HEART, i); l d[i+12] = c; l } l for(int i = 1; i < 14; ++i){ l card c(suit:: DIAMOND, i); l d[i+25] = c; l } l for(int i = 1; i < 14; ++i){ l card c(suit:: CLUB, i); l d[i+38] = c; l } l }
C++ for C Programmers by Ira Pohl
C11 auto feature
l void print (vector <card> & deck) l { l for(auto p = deck.begin(); p!= deck.end(); ++p) l cout << *p; l cout << endl; l } l bool is_flush(vector < card > & hand) l { l suit s = hand[0].get_suit(); l for(auto p = hand.begin() + 1; p!= hand.end(); ++p) l if (s != p -> get_suit()) l return false; l return true; l }
C++ for C Programmers by Ira Pohl
Answer:
l void print (vector <card> & deck) l { l for(auto cardval:deck)
§ cout << cardval; l cout << endl; l }
C++ for C Programmers by Ira Pohl
straight
l bool is_straight(vector < card > & hand){ l int pips_v[5], i = 0; l for(auto p = hand.begin(); p!= hand.end(); ++p) l pips_v[i++] = (p -> get_pips()).get_pips(); l sort(pips_v, pips_v +5); //stl iterator range l if (pips_v[0] != 1) //non-aces l return ( pips_v[0] == pips_v[1] -1 && pips_v[1] == pips_v[2] -1 ) l && ( pips_v[2] == pips_v[3] -1 && pips_v[3] == pips_v[4] -1 ); l else //aces have a special logic l return ( pips_v[0] == pips_v[1] -1 && pips_v[1] == pips_v[2] -1 ) l && ( pips_v[2] == pips_v[3] -1 && pips_v[3] == pips_v[4] -1 ) l || (pips_v[1] == 10)&&(pips_v[2] == 11)&&(pips_v[3] ==12)&& l (pips_v[4] == 13); l }
C++ for C Programmers by Ira Pohl
So straight flush is easy
l bool is_straight_flush(vector < card > & hand){
l return is_flush(hand) && is_straight(hand); l }
C++ for C Programmers by Ira Pohl
Set up simulation
l int main() l { l vector < card > deck(52); l srand(time(0)); l init_deck(deck); l int how_many ; l int flush_count = 0; l int str_count = 0; l int str_flush_count = 0; l cout << " How Many shuffles?"; l cin >> how_many;
C++ for C Programmers by Ira Pohl
STL use to run simulation
l for(int loop = 0; loop < how_many; ++loop){ l random_shuffle(deck.begin(), deck.end()); //STL algorithm l vector <card> hand(5); l int i = 0; l for( auto p = deck.begin(); i < 5; ++p) l hand[i++] = *p; l if (is_flush(hand)) l flush_count++; l if (is_straight(hand)) l str_count++; l if (is_straight_flush(hand)) l str_flush_count++ ; l } l cout << " Flushes " << flush_count << " out of " << how_many << endl; l cout << " Straights " << str_count << " out of " << how_many<< endl; l cout << " Straight Flushes " << str_flush_count << " out of " l << how_many << endl;
C++ for C Programmers by Ira Pohl
Quiz at home
l Write is_4of_akind()
l Write is_straight_flush() for 7 card stud or 5 card draw.
C++ for C Programmers by Ira Pohl
Bidirectional Iterator
l The bidirectional iterator must allow the elements to be searched in both a forward direction and backward direction.
l This requires the operation on a forward iterator ++ operator -- ("back up the iterator").
C++ for C Programmers by Ira Pohl
reverse
l A canonical algorithm using this iterator is the STL reverse() algorithm: template<typename T> void reverse(BidirectionalIterator first, BidirectionalIterator last); This algorithm reverses the elements in the specified iterator range.
C++ for C Programmers by Ira Pohl
Move both ends
l Front++ l Back—
l So swap and move would lead to reverse
C++ for C Programmers by Ira Pohl
isPalindrome
l template<typename Bidirectional> bool isPalindrome(Bidirectional first, Bidirectional last) { while( true ){ last--; if(first == last) //assume >= undefined
break; if(*first != *last)
return false; first++; if(first == last)
break; } return true; }
C++ for C Programmers by Ira Pohl
How it works
l The algorithm moves forward and backward testing each position for equality.
l It checks if a value is not equal and returns false.
l If all values
test as equal then the iterators "meet in the middle" (or pass each other) and it returns true.
l Compare to how you would do this with a forward only iterator - becomes n*n
C++ for C Programmers by Ira Pohl
Random access Iterator
l The random access iterator must allow the elements to be randomly searched in fixed time. Think indexed array.
l This requires effectively being able to add or subtract to an iterator value and retrieve a value from the computed position.
l It also means that iterator values can be compared for less and greater than as well as equality operators.
C++ for C Programmers by Ira Pohl
Sort() -hoare quicksort
l A canonical algorithm using this iterator is the STL sort() algorithm: template<class T> void sort(RandomAccessIterator first, RandomAccessIterator last);
C++ for C Programmers by Ira Pohl
Pick an element at random
l template< typename RandomAccess> RandomAccess pickRandEl( RandomAccess first, RandomAccess last) { ptrdiff_t temp = last-first; return first + rand()%temp; }
C++ for C Programmers by Ira Pohl
ptrdiff_t
l #include<cstddef> //ptrdiff_t l ptrdiff_t. type. <cstddef>. Result of pointer
subtraction. This is the type returned by the subtraction operation between two pointers. This is a signed integral type.
C++ for C Programmers by Ira Pohl
Standard Template Library
l Standard template library accepted in July 1994 into C++ ANSI Standard
l STL library provides containers, iterators and algorithms designed to l work efficiently l work parametrically l work orthogonally
C++ for C Programmers by Ira Pohl
l Sequence - ordered by sequence of elements
l Associative - keys for looking up elements
Two Varieties of Containers
vector!list!deque!
set! map! multimap!multiset!
C++ for C Programmers by Ira Pohl
Typical Container Interfaces
l Constructors l default constructors, copy constructors
l Element access l Element insertion l Element emplacement -new C++11(&&) l Element deletion l Destructor l Iterators
C++ for C Programmers by Ira Pohl
Overview of Containers
l Common set of properties l Constructors and destructors l Element access, insertion and deletion l Allocate and manage memory
l Associated allocator objects
C++ for C Programmers by Ira Pohl
Associative Containers
l Key based accessible elements
l Ordering relation Compare l Comparison object for the associative container
set! map! multimap!multiset!
C++ for C Programmers by Ira Pohl
Unordered_map
l C++11 introduces “hash” based lookup for map and set
l unordered_map -uses hash lookup l unordered_set - uses hash lookup
l Advantage – much of the time O(1) lookup
C++ for C Programmers by Ira Pohl
MAP Program
l #include <map> l #include <unordered_map> l #include <string> l #include <iostream> l using namespace std; l //we will use both types of map
C++ for C Programmers by Ira Pohl
MAP Program l int main() l { l map<unsigned long, string> worker; l unordered_map<unsigned long, unsigned> payroll; l unsigned total_pay =0; l worker[99567800] = "Harold Fish"; l payroll[99567800] = 67300; l worker[8567800] = "Phillip Fish"; l payroll[89567800] = 87300;
C++ for C Programmers by Ira Pohl
MAP
l Worker links id number to name
l Payroll links id number to salary
l Ordinary map red-black tree
l Unordered map hash
C++ for C Programmers by Ira Pohl
MAP
l for(auto p = worker.begin(); p != worker.end(); ++p) l cout << "name " << (*p).second << "\t id no. " << (*p).first << endl;
l //associate (first, second) l // (id no, name)
C++ for C Programmers by Ira Pohl
MAP
l for(auto p = payroll.begin(); p != payroll.end(); ++p) l total_pay += (*p).second;
l cout << "payroll totals $"<< total_pay << endl;
C++ for C Programmers by Ira Pohl
STL Algorithms Library
l Sorting algorithms l Non-mutating sequence algorithms l Mutating sequence algorithms l Numerical algorithms l Generally use iterators to access containers
instantiated on given type l Resulting code can be competitive in efficiency with
special purpose codes
C++ for C Programmers by Ira Pohl
Sorting Algorithm Prototypes
l template<class RandAcc> void sort(RandAcc b, RandAcc e); l Quicksort algorithm over elements b to e
l
template<class RandAcc> void stable_sort(RandAcc b, RandAcc e); l Stable sorting algorithm over elements b to e
l Elements remain in their relative same position
C++ for C Programmers by Ira Pohl
Non-Mutating Sequence Algorithms
l Do not modify contents of the containers they work on
l Typical operation is searching container for particular element and returning its position
C++ for C Programmers by Ira Pohl
Non-mutating Algorithm
l template<class InputIter, Class T> InputIter find(InputIter b, InputIter e, const T& t)); l Finds position of t in range b to e
l template<class InputIter, Class Predicate> InputIter find(InputIter b, InputIter e, Predicate p)); l Finds position of first element that makes predicate true in
range b to e, otherwise position e returned
C++ for C Programmers by Ira Pohl
Non-mutating Algorithm Prototypes (2 of 2)
l template<class InputIter, Class Function> void for_each(InputIter b, InputIter e, Function f)); l Apply f to each value found in range b to e
C++ for C Programmers by Ira Pohl
Example: Algorithm find()
l int main() // find pos of "hop" { string words[5] = { "my", "hop", "mop", "hope", "cope"}; string* where;
where = find(words, words + 5, "hop"); cout << *++where << endl; //mop sort(words, words + 5); where = find(words, words + 5, "hop"); cout << *++where << endl; //hope }
C++ for C Programmers by Ira Pohl
Lambda Expressions; for_each Expression
l Derived from Lisp
l Previously for_each needs a function
l Will use new C++11 idea – write an unnamed function in place – a lambda expression
C++ for C Programmers by Ira Pohl
Old style for_each()
l #include <algorithm> l #include <vector> l #include <iostream> l using namespace std;
l void incr(int &i){static int n = 1; i = n++;} l void outvec(int i){cout <<i << endl;}
l int main() l { l vector <int> v(6); l for_each(v.begin(), v.end(), incr ); l for_each(v.begin(), v.end(), outvec ); l }
C++ for C Programmers by Ira Pohl
What got printed?
l vector <int> v(6); l for_each(v.begin(), v.end(), incr ); l for_each(v.begin(), v.end(), outvec ); l }
C++ for C Programmers by Ira Pohl
Lambda C++11
l Taken from LISP
l Unnamed function l [](int i){cout <<i << endl;} l //goes where the function object is required
C++ for C Programmers by Ira Pohl
returns Lambda C++11
l [] (int n) { return n * 5.5; }//double l // deduces the return value –no return void l [] (int n) -> int { return ++n; } //explicit
l Read wikipedia about Lambda
C++ for C Programmers by Ira Pohl
Mutating Function
l template<class InputIter, class OutputIter> OutputIter copy(InputIter b1, InputIter e1, OutputIter b2); l Copying algorithm over elements b1 to e1
l Copy is placed starting at b2 l Position returned is end of copy
C++ for C Programmers by Ira Pohl
Suggested work
l Write a small program with vectors that tests using copy()
C++ for C Programmers by Ira Pohl
Numerical Algorithms
l Sums l Inner product l Adjacent difference l Numerical Algorithm functions behave as
expected on numerical types where + and * are defined
C++ for C Programmers by Ira Pohl
Numerical Algorithm Program
l int main() { double v1[3] = { 1.0, 2.5, 4.6 }, v2[3] = { 1.0, 2.0, -3.5 }; double sum, inner_p;
l sum = accumulate(v1, v1 + 3, 0.0); inner_p = inner_product(v1, v1 + 3, v2, 0.0); cout << "sum = " << sum << ", product = " << inner_p << endl; }
C++ for C Programmers by Ira Pohl
Numerical Algorithm Prototypes (1 of 2)
l template<class InputIter, class T> T accumulate(InputIter b, InputIter e, T t); l Standard accumulation algorithm whose sum is
initially t l Successive elements from the range b to e are added
to sum
C++ for C Programmers by Ira Pohl
Numerical Algorithm Prototypes (2 of 2)
l template<class InputIter, class T, class BinOp> T accumulate(InputIter b, InputIter e, T t, BinOp bop); l Accumulation whose sum is initially t
l Successive elements from range b to e are summed with sum = bop(sum, element)
C++ for C Programmers by Ira Pohl
Function Objects
l Useful to have function objects to further leverage STL library l Numerical functions have built-in meaning using + or
*, as well as user-provided binary operators which could be passed in
l Defined function objects can be found in function.h or built
l Function objects are classes that have operator() defined l Inlined, compiled producing efficient object code"
C++ for C Programmers by Ira Pohl
Function Object for minus<int>
l int main() { double v1[3] = {1.0, 2.5, 4.6}, sum; sum = accumulate(v1, v1 + 3, 0.0, minus<int>()); cout << "sum = " << sum << endl;
l //sum = -7 } l Accumulation using integer minus for binary
operation over the array v1[]
C++ for C Programmers by Ira Pohl
Generator Object and Integration
l // The function is represented in class gen
l class gen { // generator for integrated function l public: l gen(double x_zero, double increment) l : x(x_zero), incr(increment) { } l double operator()() { x += incr; return x * x; } l private: l double x, incr; l };
C++ for C Programmers by Ira Pohl
integrate
l double integrate(gen g, int n) l // integrate on (0,1) l { l vector<double> fx(n);
l generate(fx.begin(), fx.end(), g); l return l (accumulate(fx.begin(), fx.end(), 0.0) / n); l }
C++ for C Programmers by Ira Pohl
End of code
l int main() l { l const int n = 10000;
l gen g(0.0, 1.0/n); l cout << "integration program x**2" << endl; l cout << integrate(g, n) << endl; l }
C++ for C Programmers by Ira Pohl
Defined Function Object Classes
l Arithmetic objects
l Comparison objects
l Logical objects
C++ for C Programmers by Ira Pohl
Arithmetic Objects (1 of 2)
l template <class T> struct plus<T> l Adds two operands of type T
l template <class T> struct minus<T> l Subtracts two operands of type T
l template <class T> struct times<T> l Multiplies two operands of type T
C++ for C Programmers by Ira Pohl
Arithmetic Objects (2 of 2)
l template <class T> struct divides<T> l Divides two operands of type T
l template <class T> struct modulus<T> l Modulus (%) for two operands of type T
l template <class T> struct negate<T> l Unary minus for one argument of type T
C++ for C Programmers by Ira Pohl
Function Adapters
l Creation of function objects using adaption
l Negators for negating predicate objects
l Binders for binding a function argument
l Adapters for pointer to function
C++ for C Programmers by Ira Pohl
Use of Function Adapter bind2nd (1 of 2)
l template <class ForwIter> void print(ForwIter first, ForwIter last,
l const char* title) { cout << title << endl; while( first != last) cout << *first++ << '\t'; cout << endl; }
C++ for C Programmers by Ira Pohl
Use of Function Adapter bind2nd (2 of 2) l // use a binder function bind2nd to transform initial sequence of //
values to these values doubled l int main()
{ int data[3] = { 9, 10, 11}; print(data, data + 3, "Original values"); transform(data, data + 3, data, bind2nd(times<int>(), 2)); print(data, data + 3, "New values"); }
C++ for C Programmers by Ira Pohl
STL Based on Templates
l Key to understanding STL is to use iterator logic
l When extending STL keep consistent with existing libraries
l Generality and genericity are not enough:
It’s not STL if it isn’t efficient