2018 Sun Moon Lake Marathon 1028 Sun 29

  • Slides: 68
Download presentation
2018 Sun Moon Lake Marathon 10/28 (Sun) 29 km or 42 km p 6/15

2018 Sun Moon Lake Marathon 10/28 (Sun) 29 km or 42 km p 6/15 (Fri) 報名截止 FB: 資 鐵人 p 1

Overloaded Function (P. 237) Recall “function overloading” on P. 237 p We have three

Overloaded Function (P. 237) Recall “function overloading” on P. 237 p We have three functions with the same name: p n n n p int max(int x[], int len); long max(long x[], int len); double max(double x[], int len); The code is essentially the same for each function, but with different parameter types. 2

Ex 6_07. cpp // Maximum of ints int max(const int x[], const size_t len)

Ex 6_07. cpp // Maximum of ints int max(const int x[], const size_t len) { int maximum = x[0] ; for (size_t i=1; i < len; i++) if(maximum < x[i]) maximum = x[i]; return maximum; } // Maximum of longs long max(const long x[], const size_t len) { long maximum = x[0] ; for (size_t i=1; i < len; i++) if(maximum < x[i]) maximum = x[i]; return maximum; } // Maximum of doubles double max(const double x[], const size_t len) { double maximum = x[0] ; for (size_t i=1; i < len; i++) if(maximum < x[i]) maximum = x[i]; return maximum; } 3

Function Templates (P. 241) C++ compiler can automatically generate functions with various parameter types.

Function Templates (P. 241) C++ compiler can automatically generate functions with various parameter types. p The functions generated by a function template all have the same basic code, but customized by the type arguments that you supply. p 4

Function Templates (P. 241) type parameter template <typename T> T max (const T x[],

Function Templates (P. 241) type parameter template <typename T> T max (const T x[], int len) { T maximum = x[0] ; for (size_t i = 1; i < len; i++) if (maximum < x[i]) maximum = x[i]; return maximum; } 5

Instantiation T is replaced by a specific type argument, such as “long” long max

Instantiation T is replaced by a specific type argument, such as “long” long max (const long x[], int len) { long maximum =x[0]; for (size_t i = 1; i < len; i++) if (maximum < x[i]) maximum = x[i]; return maximum; } 6

Ex 6_08. cpp (P. 243) #include <iostream> using std: : cout; using std: :

Ex 6_08. cpp (P. 243) #include <iostream> using std: : cout; using std: : endl; // Template for function to compute the maximum element of an array template<typename T> T max(T x[], int len) { T maximum(x[0]); for(int i = 1; i < len; i++) if(maximum < x[i]) maximum = x[i]; return maximum; } 7

Ex 6_08. cpp (cont. ) int main(void) { int small[] = { 1, 24,

Ex 6_08. cpp (cont. ) int main(void) { int small[] = { 1, 24, 34, 22}; long medium[] = { 23, 245, 123, 1, 2345}; double large[] = { 23. 0, 1. 4, 2. 456, 345. 5, 12. 0, 21. 0}; int lensmall(sizeof small/sizeof small[0]); int lenmedium(sizeof medium/sizeof medium[0]); int lenlarge(sizeof large/sizeof large[0]); cout << endl << max(small, lensmall); cout << endl << max(medium, lenmedium); cout << endl << max(large, lenlarge); cout << endl; return 0; } 8

Class Templates (P. 362) 9

Class Templates (P. 362) 9

Chapter 10 Standard Template Library (STL) 10

Chapter 10 Standard Template Library (STL) 10

The Standard Template Library (P. 479) The STL is a large collection of class

The Standard Template Library (P. 479) The STL is a large collection of class templates and function templates provided with your native C++ compiler. p STL provides class templates that relieves you of the trouble of memory management. p In the class of Data Structure, you will learn how to implement these by yourselves: p n vector, list, hash, set, queue, stack 11

Some useful STL class templates p vector n n p deque n n p

Some useful STL class templates p vector n n p deque n n p an array that can increase in capacity automatically when required. You can only add new elements efficiently to the end of a vector. Double-ended queue Equivalent to a vector but you can add elements to the beginning efficiently. list n a doubly-linked list 12

Figure 10 -2 (P. 491) 13

Figure 10 -2 (P. 491) 13

Creating Vector Containers p Containers (P. 480) are objects that you use to store

Creating Vector Containers p Containers (P. 480) are objects that you use to store and organize other objects. n n an int vector – an array of integers a string vector – an array of strings Instead of defining CInt_Vector, CFloat_Vector, CString_Vector, you have a class template vector<T>. p Creating vector<T> containers: p n n n vector<string> strings; vector<double> data; vector<int> mydata; 14

A Simple Example #include <iostream> #include <vector> using std: : cout; using std: :

A Simple Example #include <iostream> #include <vector> using std: : cout; using std: : endl; using std: : vector; int main() { vector<int> mydata; mydata. push_back(98); mydata. push_back(99); mydata. push_back(100); Visual C++ implements this as a 4 -byte unsigned integer On STU, clang++ implements this as an 8 -byte unsigned integer for (size_t i=0; i<mydata. size(); i++) cout << mydata[i] << ' '; cout << endl; return 0; } 15

Create a Vector p vector<int> mydata; mydata. push_back(99); n p vector<int> mydata(100); n p

Create a Vector p vector<int> mydata; mydata. push_back(99); n p vector<int> mydata(100); n p If you add new elements to this vector, the memory allocated for the vector will be increased automatically. Create a vector that contains 100 elements that are all initialized to zero. vector<int> mydata(100, -1); n Create a vector that contains 100 elements that are all initialized to -1. 16

Create a Vector (cont. ) p Create a vector with initial values for elements

Create a Vector (cont. ) p Create a vector with initial values for elements from an external array. n int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; vector<int> mydata(data, data+8); // mydata will contain 1 2 3 4 5 6 7 8 n You may also specify vector<int> hisdata(mydata. begin()+1, mydata. end()-1); // hisdata will contain 2 3 4 5 6 7 p A sequence of elements is specified in the STL by two iterators (imagine iterators as something like pointers, P. 483): § begin() pointing to the first element in the sequence § end() pointing to one past the last element in the sequence 17

Iterator p p p Iterate over all the elements in the sequence by incrementing

Iterator p p p Iterate over all the elements in the sequence by incrementing the begin iterator until it equals the end iterator. Suppose mydata contains 1 2 3 4 5 6 7 8 vector<double> values(mydata. begin()+2, mydata. end()-1) // values will contain 3 4 5 6 7 p Note the end iterator points to one past the last element. p Reverse iterator: rbegin() and rend(). 18

Capacity and Size of a Vector Container capacity() – the maximum number of objects

Capacity and Size of a Vector Container capacity() – the maximum number of objects a container can currently accommodate. p size() – the number of objects stored in the container. p empty() – Boolean function which tests whether size() is 0. p Both values are returned as type vector<T>: : size_type p n In Visual C++, this is implemented as size_t, a 19 4 -byte unsigned integer.

Resize a Vector p p vector<int> values(5, 66); // 66 66 66 values. resize(7,

Resize a Vector p p vector<int> values(5, 66); // 66 66 66 values. resize(7, 88); // 66 66 66 88 88 values. resize(10); // 66 66 66 88 88 0 0 0 // If you don’t specify a value for new elements, // the default value of the object will be produced. values. resize(4); // 66 66 20

Ex 10_01. cpp (P. 496) p list. Info(vector<T> &v) n n p p pass-by-reference

Ex 10_01. cpp (P. 496) p list. Info(vector<T> &v) n n p p pass-by-reference runs faster if the vector is very large Output the elements with a loop n You may also use the auto keyword for (auto i = 0; i<numbers. size(); i++) cout << " " << numbers[i]; n Or using an iterator for (vector<int>: : iterator iter = numbers. begin(); iter < numbers. end(); iter++) cout << " " << *iter; Observe how the capacity grows. 21

Accessing Elements in a Vector p Use the subscript operator, just like an array

Accessing Elements in a Vector p Use the subscript operator, just like an array n p cout << numbers[i]; Use the at() function where the argument is the index position. n cout << numbers. at(i); 22

Inserting and Deleting Elements in a Vector (P. 500) push_back(); p pop_back(); p clear();

Inserting and Deleting Elements in a Vector (P. 500) push_back(); p pop_back(); p clear(); p n the size will be 0; the capacity will be left unchanged. insert(); p erase(); p n Both the erase() and insert() operations are slow. 23

Storing Objects in a Vector p Person. h (P. 504) n n n A

Storing Objects in a Vector p Person. h (P. 504) n n n A class defining people by their name show. Person() init. Name() is invoked by Constructor p Copy constructor p Assignment operator p p Ex 10_02. cpp 24

Sorting Vector Elements p sort(data, data+count); n p Note the pointer marking the end

Sorting Vector Elements p sort(data, data+count); n p Note the pointer marking the end of the sequence of elements must be one past the last element. sort(data, data+count, greater<int>()); n n Sorting in descending order. Remember to “using std: : greater” 25

Exercises 1. 2. Modify Ex 10_02. cpp, so that after the input names are

Exercises 1. 2. Modify Ex 10_02. cpp, so that after the input names are printed out, print a separator consisting of dashes (-), whose total length is the same as the longest name, and then print out all names in sorted ascending order. Redefine the operator< in Person. h, so that when we compare two names, the longer one is regarded as larger (e. g. “Yankee” < “Elizabeth”). If two names have the same length, then compare their alphabetic order. 26

Double-Ended Queue p deque<T> - the double-ended queue container template n It is similar

Double-Ended Queue p deque<T> - the double-ended queue container template n It is similar to a vector. It can do everything a vector container can. p It includes the same function members. p n But you can add and delete elements efficiently at the beginning as well as at the end. push_front() p pop_front() p 27

Ex 10_04. cpp (P. 513) p Create the container and two iterator variables: n

Ex 10_04. cpp (P. 513) p Create the container and two iterator variables: n n n p deque<int> data; deque<int>: : iterator iter; deque<int>: : reverse_iterator riter; while (cin >> value, value !=0) n n separating two expressions with the comma operator. The value of a series of expressions separated by commas is the value of the rightmost expression. (P. ? ? ) (P. 60) 28

Ex 10_04. cpp (cont. ) p Use iter as the loop control variable to

Ex 10_04. cpp (cont. ) p Use iter as the loop control variable to output the values. n The loop ends when iter is incremented to be equal to the iterator returned by the end() function. p p iter = data. begin(); while (iter != data. end()) cout << *iter++ << “ “; Use a reverse iterator riter to output the values in reverse order p for (riter = data. rbegin() ; riter != data. rend(); riter++) cout << *riter << “ “; 29

Accumulate() Algorithm p accumulate(data. begin(), data. end(), 0) p Although you could use a

Accumulate() Algorithm p accumulate(data. begin(), data. end(), 0) p Although you could use a conventional loop to do this, you may make use of the accumulate() algorithm (defined in the numeric header) to calculate the sum. n n The first two arguments specify the iterators defining the sequence of elements. The third argument specifies an initial value for the sum (which is generally 0). 30

Sorting a Double-Ended Queue p The default operation of the sort() algorithm is to

Sorting a Double-Ended Queue p The default operation of the sort() algorithm is to sort the sequence in ascending order. n n p sort (data. begin(), data. end() ); sort (data. rbegin(), data. rend() ); Pass reverse iterators to sort() will make it see the elements in reverse order, and sorts the sequence in descending order. n Let’s have an exercise on Bubble Sort. 31

Bubble Sort Compare 2 to 7; p 2 is smaller than 7 so swap

Bubble Sort Compare 2 to 7; p 2 is smaller than 7 so swap them p 9 5 7 2 32

Bubble Sort Compare 2 to 5; p 2 is smaller than 5 so swap

Bubble Sort Compare 2 to 5; p 2 is smaller than 5 so swap them p 9 9 5 5 7 2 2 7 33

Bubble Sort Compare 2 to 9; p 2 is smaller than 9 so swap

Bubble Sort Compare 2 to 9; p 2 is smaller than 9 so swap them p 9 9 9 5 5 2 7 2 5 2 7 7 34

p Bubble Sort After the first round you see 2 (the smallest element) is

p Bubble Sort After the first round you see 2 (the smallest element) is on the top 9 9 9 2 5 5 2 9 7 2 5 5 2 7 7 7 35

Bubble Sort Compare 5 to 7; p 5 is smaller than 7 so leave

Bubble Sort Compare 5 to 7; p 5 is smaller than 7 so leave them alone p 2 9 5 7 36

Bubble Sort Compare 9 to 5; p 9 is greater than 5 so swap

Bubble Sort Compare 9 to 5; p 9 is greater than 5 so swap them p 2 2 9 9 5 5 7 7 37

Bubble Sort 2 2 2 9 9 5 5 5 9 7 7 7

Bubble Sort 2 2 2 9 9 5 5 5 9 7 7 7 p After the 2 nd round, the 2 nd smallest element (5) also rises to the correct position. 38

Bubble Sort Compare 9 to 7; p 9 is greater than 7 so swap

Bubble Sort Compare 9 to 7; p 9 is greater than 7 so swap them p 2 5 9 7 39

Bubble Sort p 2 2 5 5 9 7 7 9 At the end

Bubble Sort p 2 2 5 5 9 7 7 9 At the end of the 3 rd round, the sequence is sorted in ascending order. 40

Exercise: Bubble Sort on deque<T> Define your own class my. Queue. p Create a

Exercise: Bubble Sort on deque<T> Define your own class my. Queue. p Create a member function bsort(). p n n The function takes two arguments which are iterators specifying the sequence of elements to be sorted. The function will print out the sequence during the sorting process. For example 0: p 1: p 2: p 3: p [9 [2 [2 [2 5 9 5 5 7 5 9 7 2] (before sorting) 7] 7] 9] (after sorting) 41

Performance Consideration p Because of the additional capability it offers, the memory management for

Performance Consideration p Because of the additional capability it offers, the memory management for a double-ended queue is more complicated than for a vector, so it will be slightly slower. (P. 513) p Let’s try to measure how “slower” it is. 42

Measure the running time of a program #include <iostream> #include <time. h> using std:

Measure the running time of a program #include <iostream> #include <time. h> using std: : cout; using std: : endl; int main() { const int K = 10000; clock_t t 0, t 1; t 0 = clock(); for (int i=0; i<K; i++) for (int j=0; j<K; j++); t 1 = clock(); cout << "CLOCKS_PER_SEC = " << CLOCKS_PER_SEC << endl; cout << t 0 << 't' << t 1 << endl; cout << static_cast<float>(t 1 - t 0) / CLOCKS_PER_SEC << endl; return 0; } 43

time() p You may also get the current time (wallclock time): #include <iostream> #include

time() p You may also get the current time (wallclock time): #include <iostream> #include <time. h> using std: : cout; using std: : endl; int main() { time_t t 0; cout << "Seconds elapsed since " << "0 hours, 0 minutes, 0 seconds, January 1, 1970: " << time(&t 0) << endl; return 0; } Seconds elapsed since 0 hours, 0 minutes, 0 seconds, January 1, 1970: 1335937264 44

Interpret the Output of time() p Seconds elapsed since 0 hours, 0 minutes, 0

Interpret the Output of time() p Seconds elapsed since 0 hours, 0 minutes, 0 seconds, January 1, 1970: 1335937264 n n n 1335937264 86400 = 15462 … 20464 3600 = 5 … 2464 60 = 41 … 4 Current time (HH: MM: SS) is 05: 41: 04 GMT (Greenwich Mean Time) + 8 = TWN So the local time in Taiwan is 13: 41: 04. 45

ctime() and localtime() #include <iostream> #include <time. h> You may convert it to a

ctime() and localtime() #include <iostream> #include <time. h> You may convert it to a well -formatted string, using std: : cout; using std: : endl; int main() { time_t t 0; struct tm *new. Time; time(&t 0); cout << ctime(&t 0); new. Time = localtime( &t 0 ); cout << new. Time->tm_hour << ': ' << new. Time->tm_min << ': ' << new. Time->tm_sec << endl; return 0; } or break the time information to several fields. int int 0) int tm_sec; tm_min; tm_hour; tm_mday; tm_mon; tm_year; tm_wday; // // seconds (0 - 60) minutes (0 - 59) hours (0 - 23) day of month (1 - 31) month of year (0 - 11) year - 1900 day of week (Sunday = tm_yday; // day of year (0 - 365) 46

Exercise on vector p Create a vector n n Iteratively add 10000 elements to

Exercise on vector p Create a vector n n Iteratively add 10000 elements to the end by push_back(). Calculate the average time for adding a new element. Iteratively delete elements from the end by pop_back(). Calculate the average time for deleting an element. Iteratively add 10000 elements to the beginning by insert(). Calculate the average time for adding a new element. Iteratively erase elements from the beginning by erase(). Calculate the average time for deleting an element. 47

Exercise on deque p Create a deque n n p Iteratively add 10000 elements

Exercise on deque p Create a deque n n p Iteratively add 10000 elements to the end by push_back(). Calculate the average time for adding a new element. Iteratively delete elements from the end by pop_back(). Calculate the average time for deleting an element. Iteratively add 10000 elements to the beginning by push_front(). Calculate the average time for adding a new element. Iteratively erase elements from the beginning by pop_front(). Calculate the average time for deleting an element. You may measure by clock() or time(). Post your result to Moodle, by specifying how you measure 48 the time.

List p List<T> - the list container template n p You can insert or

List p List<T> - the list container template n p You can insert or delete elements anywhere in the sequence in constant time. See figures in P. 491 49

Create a List p list<string> names; n p Create an empty list List<string> sayings(20);

Create a List p list<string> names; n p Create an empty list List<string> sayings(20); n A list of 20 empty strings p list<double> values(50, 2. 71828); p A list of 50 values of type double; list<double> samples(++values. begin(), -values. end()); n n n Copy the contents from the values list, except the first and the last elements You do not have random access iterators as 50 with a vector or a deque container.

Adding Elements to a List push_front() p push_back() p insert() p n n list<int>

Adding Elements to a List push_front() p push_back() p insert() p n n list<int> data(5, 1); // P. 518 data. insert(++data. begin(), 77); data. insert(iter, 3, 88); data. insert(iter, numbers. begin(), numbers. end()); 51

Accessing Elements in a List front(), back() p Using an iterator p n n

Accessing Elements in a List front(), back() p Using an iterator p n n begin(), end() rbegin(), rend() You can only increment or decrement an iterator. Random access like begin()+2 is not allowed. Note that in Ex 10_05. cpp, the code is iter != text. end() instead of iter < text. end() because lists only have bidirectional iterators, 52 not random access iterators.

Ex 10_05. cpp (P. 515) p Enter a few lines of text. Press Enter

Ex 10_05. cpp (P. 515) p Enter a few lines of text. Press Enter to end. n n push_front() making the lines to be stored in reverse order. Replace it as push_back() to see the difference. Output the data using an iterator. p Sort the data in ascending sequence. p n The list<T> templates defines its own sort() function member, because the sort() function defined in the algorithm header requires a random access iterator. 53

Other Operations on Lists p clear() n p erase(iter) n p Remove an element

Other Operations on Lists p clear() n p erase(iter) n p Remove an element from a list erase(numbers. begin(), numbers. end()) n p Delete all the elements from a list Remove elements from a list merge() n Merge two sorted lists 54

Other Operations on Lists (cont. ) p remove() n p Remove elements from a

Other Operations on Lists (cont. ) p remove() n p Remove elements from a list that match a particular value unique() n n n Eliminate adjacent duplicate elements list data[] = {10, 22, 4, 10, 89, 22, 89, 10}; list<int> numbers(data, data+8); numbers. remove(22); numbers. sort(); numbers. unique(); 55

Ex 10_06. cpp (P. 520) p Defining a Predicate for Filtering a List n

Ex 10_06. cpp (P. 520) p Defining a Predicate for Filtering a List n p members. remove_if(is_negative<int>()); Note the two function templates list() and loadlist(). 56

Exercise p We are interested in 3 fields in a text file: n n

Exercise p We are interested in 3 fields in a text file: n n n p p 11 -21 24 -39 41 -55 Define a class CEntry with three data members (id, nickname, source). Write a C++ program to read the file, and store the fields to a list of CEntry. Now enter an infinite loop to ask users to supply an id. Search the list to determine whether this id appears in the list. n p id nickname source Bonus: also display the time which the computer took to search each id. End the program when the user inputs an empty string. 57

// This code fragment will extract the three fields from the file #include <iostream>

// This code fragment will extract the three fields from the file #include <iostream> #include <fstream> #include <string> Hint using std: : cout; std: : endl; std: : ifstream; std: : string; int main() { string line; ifstream user("T: \ptt-user. txt"); while (getline(user, line, 'n') ) { cout << line. substr(10, 11) << 't' << line. substr(23, 16) << 't' << line. substr(40, 15) << endl; } return 0; } 58

Associate Containers (P. 543) p map<K, T> n n n p You don’t need

Associate Containers (P. 543) p map<K, T> n n n p You don’t need to search the whole list to retrieve a particular object. The location of an object of type T within an associative container is determined from a key of type K. The mechanism is also known as dictionary or hash. The objects you store in a map are always a key/object pair n The template type pair<K, T> is automatically included by the map header. 59

#include <iostream> #include <map> #include <string> using A Simple Example std: : cout; std:

#include <iostream> #include <map> #include <string> using A Simple Example std: : cout; std: : endl; std: : string; std: : map; int main() { map<string, int> score; score["Alice"] = 100; score["Bob"] = 70; score["Charlie"] = 60; cout << score["Bob"] << endl; cout << score. size() << endl; return 0; } 60

#include <iostream> #include <string> #include <map> using std: : cin; using std: : cout;

#include <iostream> #include <string> #include <map> using std: : cin; using std: : cout; using std: : endl; using std: : string; using std: : map; fruit_count int main() { string fruit; map<string, int> fruit_count; for (int i=0; i<5; i++) { cin >> fruit; if (fruit_count. find(fruit) == fruit_count. end() ) fruit_count[fruit] = 1; else fruit_count[fruit]++; } for (map<string, int>: : iterator i = fruit_count. begin(); i != fruit_count. end(); i++) { cout << i->first << 't' << i->second << endl; } return 0; } key value Apple Banana Apple Coconut Apple 3 Banana 1 Coconut 1 61

Defining Map Containers p Creating a map n n p map<Person, string> phonebook; map<Person,

Defining Map Containers p Creating a map n n p map<Person, string> phonebook; map<Person, string> phonebook(iter 1, iter 2); Storing Objects n n auto entry = pair<Person, string>(Person(“Mel”, “Gibson”), “ 213 345 5678”); auto entry = make_pair( Person(“Mel”, “Gibson”), “ 213 345 5678”); p p make_pair() automatically deduces the type for the pair, so it looks more elegant. You may use a typedef statement to abbreviate the pair<K, T> type (P. 544) n n typedef pair<Person, string> Entry; Entry entry 1 = Entry( Person(“Jack”, “Jones”), “ 213 567 1234”); 62

insert() p Insert one or more pairs in a map n n n phonebook.

insert() p Insert one or more pairs in a map n n n phonebook. insert(entry 1); Note entry 1 is an object with the pair type The function returns a value which is also a pair: The first object is an iterator p The second is a value of type bool. p § true – the insertion was made. The iterator points to the element. § false – the insertion failed (an element with the same key already exists in the map). 63

Check if an object was stored map<Person, string> phonebook; auto checkpair = phonebook. insert(entry

Check if an object was stored map<Person, string> phonebook; auto checkpair = phonebook. insert(entry 1); if (checkpair. second) cout << “Insertion succeeded. ” << endl; else cout << “Insertion failed. ” << endl; 64

Accessing Objects p Use the subscript operator to retrieve the object from a map

Accessing Objects p Use the subscript operator to retrieve the object from a map corresponding to a key n p string number = phonebook[Person(“Jack”, “Jones”)]; However, if the key is not in the map, the subscript operator will insert a pair entry for this key, with an object of default value. n You could use the find() function to check whethere is an entry for a given key. 65

find() string number; Person key = Person(“Jack”, “Jones”); auto iter = phonebook. find(key); if

find() string number; Person key = Person(“Jack”, “Jones”); auto iter = phonebook. find(key); if (iter != phonebook. end()) { number = iter->second; cout << “The number is “ << number << endl; } else { cout << “No number for the key “; key. show. Person(); } 66

Ex 10_12. cpp (P. 549) erase() p ignore() p cout << setiosflags(ios: : left)

Ex 10_12. cpp (P. 549) erase() p ignore() p cout << setiosflags(ios: : left) p Remains in effect until the resetiosflags manipulator is used to restore rightjustification. p 67

Exercise: Map Repeat the previous exercise with BBS id. p Use a map (instead

Exercise: Map Repeat the previous exercise with BBS id. p Use a map (instead of a list) to store the data, and see whether the query speed becomes faster. p 68