Professional Documents
Culture Documents
OOP w08 Publish
OOP w08 Publish
OOP w08 Publish
1
CONTENTS
Introduction
Class Stack
Class Queue
Class Vector
Class List
Iterator design pattern
General algorithms
2
INTRODUCTION
Abstracting data help us focus on our
Abstract-Data-Type-based problems, and
not care about the object’s inside details
Containers are the critical classes
showing abstract datatype
Main goal of abstract datatypes separates
them from applications
Abstract datatypes are flexible, guarantee
their type-safe and performance
3
INTRODUCTION (CONTAINER)
Below figure show abstract objects and
their relationship
to f>>
Container
men
< < el e
// File: Object.h
#ifndef _OBJECT_H_
#define _OBJECT_H_
class Object { Stack Queue PriorityQueue Tree
public: virtual ~Object() = 0;
};
#endif
Dequeue BinaryTree
4
INTRODUCTION (CONTAINER)
Below figure show abstract objects and
their relationship
// File: Container.h
#ifndef _CONTAINER_H_ // File: Object.h
#define _CONTAINER_H_ #ifndef _OBJECT_H_
#define “Object.h” #define _OBJECT_H_
class Container { class Object {
public: public: virtual ~Object() = 0;
virtual void put(Object&) = 0; };
virtual Object& get() = 0; #endif
removeable
<<element o
virtual Object& peek() = 0;
virtual bool isEmpty() const { if(iCount == 0) return true; return false; }
virtual bool isFull() const {
> f>
if(iCount == MAX_ELEMENTS) return true; return false;
}
virtual int numberOfElems() const { return iCount; }
private: int iCount; // A number of elements of Container
Container
};
#endif 5
INTRODUCTION Stack
Source: https://en.wikipedia.org/wiki/Stack_(abstract_data_type) 6
INTRODUCTION Stack
7
INTRODUCTION Queue
Source: https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics) 8
INTRODUCTION Queue
9
INTRODUCTION PriorityQueue
Stack Queue
multiset multimap
hash_set hash_map
hash_multiset hash_multimap 17
CONTENTS
Introduction
Class Stack
Class Queue
Class Vector
Class List
Iterator design pattern
General algorithms
18
CLASS STACK
Include the library <stack>
template <class Type, class Container = deque<Type>>
class stack{}
Where:
◦ Type: datatype of members the stack contains
◦ Container: main data structure of stack
Figure:
empty() Check if empty or not
push pop
pop() Remove a member
top() Get a member
push() Add a member
top
size() Get the size of stack
19
CLASS STACK
The 1st example
#include <iostream> #include <fstream> #include <stack>
#include <list> #include <vector> #include <string>
using namespace std;
typedef stack<string> Stack1; // Default execution class
typedef stack<string, vector<string>> Stack2; // vector<string> class
typedef stack<string, list<string>> Stack3; // list<string> class
int main(int argc, char* argv[]) {
requireArgs(argc, 1); ifstream f(argv[1]); assure(f, argv[1]);
Stack1 textlines; string line;
while(getline(f, line)) textlines.push(line + “\n”);
while(!textlines.empty()){
cout << textlines.top();
textlines.pop();
}
return 0;
}
20
CLASS STACK
The 2nd example
template <class Stk> void stackOut(Stk& s, ostream& os = cout) {
while(!s.empty()) {
int main(int argc, char* argv[]) {
os << s.top() << “\n”; s.pop();
requireArgs(argc, 1);
}
ifstream f(argv[1]);
}
assure(f, argv[1]);
class Line { list<Line> lines;
string line; int lspaces;
string s;
public:
while(getline(f, s)) lines.push_front(s);
Line(string s) : line(s) {
stack<Line, list<Line>> stk(lines);
lspaces = line.find_first_not_of(‘ ’);
stackOut(stk);
if(lspaces == string::npos) lspaces = 0;
return 0;
line = line.substr(lspaces);
}
}
friend ostream& operator<<(ostream& os, const Line& L) {
for(int i = 0; i < L.lspaces; i++) os << ‘ ’;
return os << L.line;
}
// other methods…
}; 21
CLASS QUEUE
Include the library <queue>
template <class Type, class Container = deque<Type>>
class queue{}
Where:
◦ Type: datatype of members the queue contains
◦ Container: the main data structure of queue
Figure: empty() Check if empty or not
pop() Remove a member
push top() Get a member
push() Add a member
Tail
size() Get the size of stack
front back() Get the member at the end of queue
Head pop front() Get the member at the front of the queue
22
CLASS QUEUE
Example
#include <iostream> Queue q:
#include <queue> 123
#include <string> Queue q:
using namespace std; 2345
void printQueue(queue<int> q) { Current size of queue: 4
cout << “Queue q: ” << endl;
while(!q.empty()) { cout << q.front() << “ ”; q.pop() }
cout << endl;
}
void main() {
queue<int> q;
q.push(1); q.push(2); q.push(3); printQueue(q);
q.pop();
q.push(4); q.push(5); printQueue(q);
cout << “Current size of queue: ” << q.size();
}
23
CLASS VECTOR
Store the members with adjacent order as
in array
The cost of adding or removing is high
The cost of random access is low
Easily Extending the size is easier than
dynamic array
pop_back
Figure:
01 2 3 4 5 6 7
back
front push_back
24
CLASS VECTOR
Some important methods
◦ clear(): delete all members
◦ empty(): check if empty or not
◦ erase(): delete one or an array of members
◦ front(), back(): return the reference of the first and the last member
◦ insert(): add a member at another position
◦ pop_back(), push_back(): delete and add a member at the end of vector
◦ size(): return the size of vector
◦ reserve(): allocate a minimum memory for vector
◦ resize(): re-size the vector
Example
#include <iostream> 123456
#include <vector>
using namespace std;
void main() {
vector<int> coll;
for(int i = 1; i <= 6; i++) coll.push_back(i);
for(int i = 0; i < coll.size(); i++) cout << coll[i] << ‘ ’;
cout << endl;
} 25
CLASS LIST
Store the members with order of double
linked list
Adding or removing the member is quick
Random access is slow
Figure:
pop_back pop_front
push_back
push_front
26
CLASS LIST
Some important methods
◦ clear(): delete all members
◦ empty(): check if empty or not
◦ erase(): delete one or an array of members
◦ front(), back(): return the reference of the first and the last member
◦ insert(): add a member at another position
◦ pop_front(), push_front(): delete and add a member at the start of
vector
◦ pop_back(), push_back(): delete and add a member at the end of vector
◦ size(): return the size of vector
◦ merge(): join another list with current list and sort with another order
(two lists must be sorted before)
◦ splice(): join a part of another list with current list
◦ reserve(): allocate a minimum memory for vector
◦ unique(): eliminate the member with the same value
27
CLASS LIST
Example List 1: 0 1 2 3 4 5
List 2: 5 4 3 2 1 0
#include <iostream>
List 1:
#include <list>
using namespace std;
List 2: 5 4 0 1 2 3 4 5 3 2 1 0
void printList(ostream& os, list<int> &L1) { List 1: 0 0 1 1 2 2 3 3 4 4 5 5
list<int>::iterator pos = L1.begin(); List 2: 0 1 2 3 4 5
while(pos != L1.end()) {os << (*pos) << “ ”; ++pos;} List 1: 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5
os << endl; List 2:
}
void printTwoLists(ostream& os, list<int> &L1, list<int> &L2) {
os << “List 1: ”; printList(os, L1); os << “List 2: ”; printList(os, L2);
}
void main() {
list<int> l1, l2;
for(int i = 0; i < 6; i++){l1.push_back(i); l2.push_front(i);}
printTwoLists(cout, l1, l2);
l2.splice(find(l2.begin(), l2.end(), 3), l1);
printTwoLists(cout, l1, l2);
l2.sort(); l1 = l2; l2.unique();
printTwoLists(cout, l1, l2);
l1.merge(l2);
printTwoLists(cout, l1, l2);
} 28
OTHER CLASSES
“set” belongs to associative container
◦ It has no repeated member
◦ Members in “set” are sorted & saved in red-black tree
◦ Cannot directly edit a member. Need 2 steps
Delete the member of old value
Add a member with new value
“multiset” is similar to “set”, but allow repeated
value
“hash_set” and “hash_multiset” are similar to “set”
and “multiset”, but saved in hash-table
“set” and “multiset” belongs to <set>, and
“hash_set” and “hash_multiset” belongs to
<hash_set> 29
OTHER CLASSES
Example
#include <iostream> 654321
#include <set>
using namespace std;
template <class T>
void printSet(ostream& os, T& ms) {
typename T::iterator pos = ms.begin();
while(pos != ms.end()) {os << (*pos) << “ ”; ++pos;}
os << endl;
need a space
}
void main() {
set<int, greater<int> > ms;
int a[] = {2, 6, 4, 1, 5, 3}, n = sizeof(a)/sizeof(a[0]);
for(int i = 0; i < n; i++){
ms.insert(a[i]);
}
printSet(cout, ms);
} 30
OTHER CLASSES
“map” is similar to “set”, but a member in
“map” includes two parts, key and value.
And key-part must be unique
“multimap” is similar to “map”, but allow
key-part has the same value
Map Multimap
2 x 5 y 1 x 3 y
1 z 4 y 1 z 3 y
3 y 6 z 2 y 3 z
31
OTHER CLASSES
Example
#include <iostream> (1, This)(2, is)(3, an)(4, example)(5, of)(6, map)
#include <map> #include <string>
using namespace std;
template <class T> void printMap(ostream& os, T& m) {
typename T::iterator pos = m.begin();
while(pos != m.end()) {
os << “(” << pos->first << “, ” << pos->second << “)”; ++pos;
}
os << endl;
}
void main() {
map<int, string> m1; typedef pair<int, string> MyPair;
m1.insert(MyPair(2, “is”)); m1.insert(MyPair(4, “example”));
m1.insert(MyPair(3, “an”)); m1.insert(MyPair(1, “This”));
m1.insert(MyPair(6, “map”)); m1.insert(MyPair(5, “of”));
printMap(cout, m1);
} 32
ITERATOR DESIGN PATTERN
Separating the enumeration out of the set.
There are many ways of enumeration
Advantages:
◦ Can enumerate with many ways in the same
set.
◦ Simplify the class of set (because the
enumeration is separated)
◦ A set can choose many ways of enumerations
33
ITERATOR DESIGN PATTERN
Figure:
Iterator
Aggregate Client
+First()
+CreateIterator() +Next()
+IsDone()
+CurrentItem()
ConcreteAggregate
ConcreteIterator
+CreateIterator()
34
ITERATOR DESIGN PATTERN
The iterator used to enumerate in the
container is declared as follows
◦ Container_name<parameter>::iterator name
◦ Container_name<parameter>::const_iterator
name
The containers provide two basic methods
◦ begin(): return the iterator object pointing to the
first member of a set
◦ end(): return the iterator object pointing to the
member behind the last member of a set
35
ITERATOR DESIGN PATTERN
Class Iterator provides some operators:
◦ Operator *: get the value at the element (address) the iterator
object is pointing to
◦ Operator ++: the iterator object points to the next element
◦ Operator == and !=: compare two values of two iterator
objects (Consider if these two objects point to the same
address)
◦ Assignment operator ‘=’
Iterator may be classified as follows:
◦ 2-way scanning: iterator of list, set, hash_set, hash_multiset,
multiset, map, hash_map, multimap, hash_multimap (using 2
operators: ++ and --)
◦ Random access: iterator of vector and deque (using 4
operators: +=, -=, > and <) 36
ITERATOR DESIGN PATTERN
Example
#include <iostream>
#include <set> 4
using namespace std;
void main()
{
2 6
set<int> c;
int data[] = {3, 1, 5, 4, 1, 6, 2};
int n = sizeof(data) / sizeof(data[0]);
for(int i = 0; i < n; i++){
c.insert(data[i]); 1 3 5
}
set<int>::const_iterator p = c.begin();
while(p != c.end()){
cout << *p << “ ”;
++p; Enumerate with default order of a set (LNR):
} 123456
}
37
GENERAL ALGORITHMS
STL library implements some algorithms
processing the elements of Container
◦ Sort
◦ Copy
◦ Sum…
All algorithms are declared in <algorithm>
and <numeric>
◦ <numeric>: provides the methods of numeric
manipulation, such as addition or multiplication
◦ <algorithm>: provides the methods of set
manipulation, such as sort or search…
38
GENERAL ALGORITHMS
Example
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void main() {
vector<int> c; vector<int>::iterator p;
int data[] = {2, 1, 5, 4, 3, 6}, n = sizeof(data)/sizeof(data[0]);
for(int i = 0; i < n; i++) c.push_back(data[i]);
p = min_element(c.begin(), c.end());
cout << “min: ” << *p << endl;
p = max_element(c.begin(), c.end());
cout << “max: ” << *p << endl;
p = find(c.begin(), c.end(), 3);
reverse(p, coll.end());
p = coll.begin();
while(p != coll.end()){ cout << *p << ‘ ’; ++p; }
} 39
GENERAL ALGORITHMS
The algorithms interacting many sub-
array simultaneously
◦ copy(): copy the value of an array of members
to new array
◦ equal(): check if two arrays are equal or not
Example
void main(){
list<int> c1; vector<int> c2;
for(int i = 0; i < 10; i++) c1.push_back(i);
c2.resize(c1.size());
copy(c1.begin(), c1.end(), c2.begin());
}
40
COMPLEX NUMBER
STL provides template complex with
methods, operator in <complex> header
Remind:
◦ Complex x = a + bi with i2 = -1, where a is real
part and b is imaginary part
◦ Alternative form of x = r(cos + isin), where r
is modulus part and is argument part
◦ We have r = and = arctan(b/a)
◦ If x = a + bi, then = a – bi is a x’s complex
conjugate
◦ Norm of x = a + bi is a2 + b2 (norm(x) = a2 + b2)
41
COMPLEX NUMBER
Some methods:
◦ polar(): return complex number corresponding to modulus and
argument
◦ abs(): return a complex number’s modulus
◦ arg(): return a complex number’s argument
◦ conj(): return a complex conjugate
◦ imag(): return a complex’s imaginary part
◦ real(): return a complex’s real part
◦ norm(): return a norm of a complex number
◦ cos(), sin(): return a value of cos/sin function of complex number
◦ exp(): return a value of e-based exponential function of complex
number
◦ operator: addition (+, +=), subtraction (-, -=), multiplication (*,
*=), division (/, /=), assignment (=), comparison (==, !=), insertion
(<<) and extraction (>>)
42
COMPLEX NUMBER
Example:
#include <iostream> Create c1 from real and imaginary: c1 = (4,5)
#include <complex> Create c2 from c1 : c2 = (4,5)
using namespace std; c3 = polar(sqrt(8), pi / 4) = (2,2)
Modulus of c3 : abs(c3) = 2.82843
void main() {
Argument of c3 :
double pi = 3.14159265359; arg(c3) = 0.785398 radians(= 45 do).
complex<double> c1(4.0, 5.0);
cout << “Create c1 from real and imaginary: ” << “c1 = ” << c1 << endl;
complex<double> c2(c1);
cout << “Create c2 from c1: ” << “c2 = ” << c2 << endl;
complex<double> c3(polar(sqrt((double)8), pi/4));
cout << “c3 = polar(sqrt(8), pi/4) = ” << c3 << endl;
double absc3 = abs(c3);
double argc3 = arg(c3);
cout << “Modulus of c3: abs(c3) = ” << absc3 << endl;
cout << “Argument of c3:\n arg(c3) = ” << argc3 << “ radians (= ” << argc3*180/pi << “ do).” << endl;
}
43
COMPLEX NUMBER
Type conversion
◦ Also, three types including complex<float>,
complex<double> and complex<long double>
follow implicit and explicit type-casting
◦ Example:
complex<float> cf(1.0, 2.0);
complex<long double> cld(4.0, 5.0);
complex<double> cd1 = cf; // OK
complex<double> cd2 = cld; // Error
◦ Need to explicit casting
complex<double> cd2 = (complex<double>)cld; //OK
44
COMPLEX NUMBER
Comparison operator
◦ Only support “==” and “!=”, not “>” or “<”
◦ Comparing a complex with a float makes a float
to be a complex
#include <iostream>
#include <complex>
using namespace std;
void main() {
complex<double> cd(1, 0);
double d1 = 1.0;
if(d1 == cd) cout << “cd = d1” << endl;
else cout << “cd != d1” << endl;
} 45
COMPLEX NUMBER
Insertion (<<) and extraction (>>)
operators
◦ Insertion << operator follows (real, imaginary)
◦ Extraction >> operator follows (real <space>
imaginary)
#include <iostream>
#include <complex>
using namespace std;
void main() {
complex<double> cd;
cin >> cd;
cout << “So phuc da nhap: cd = ” << cd << endl;
} 46
EXERCISE (EXPRESSION)
A mathematical expression includes terms
being positive whole numbers and
operators, such as +, -, *, / or parentheses ()
Evaluate an expression and print the result
Example: 4 * (7 + 3) / 5 + 6 result = 14
Hint:
◦ Convert the expression to “reverse Polish
notation” and push it to stack
◦ Using stack to evaluate
Example: 473+*5/6+ 47
EXERCISE (EXPRESSION)
Algorithm of “reverse Polish notation”
while(expression still Has member) 4 (7 + 3) / 5 + 6
Read this member & Remove it from expression
if(this member is term) Enqueue it into result-queue
else if(this member is operator) // for example o1
while(operator o2 is top of stack)
6
if(o2 has More priority than o1)
Pop o2 from stack and Enqueue it into result-queue
5
end-while
Push o1 into stack
else if (this member is ‘(’) Push it into stack
else if(this member is ‘)’) 3 +
while(the top of stack != ‘(’)
7 (
Pop it and Enqueue into result-queue
end-while 4 +/
Pop ‘(’ from stack
end-while 4 7 3 +5 / 6 +
while(stack is not Empty)
Pop each member and Enqueue into result-queue
48
end-while
EXERCISE (EXPRESSION)
Algorithm of evaluate an expression with
“reverse Polish notation” form
while(expression still Has member) 473+5/6+
Read this member & Remove it from expression
if(this member is term) Push it into stack
else // is operator, assume we need n terms
if(a number of terms in stack < n) error “not enough terms”
else
Pop n members from stack
Compute this math
Push result of this math into stack
end-while
if (there is one member in stack) print the final result 3
else // There are more than one, so user input wrong expression
657
10
error “Error expression”
14
48
40
49
EXERCISE (GRAPH)
Let G = (V, E), where V is a collection
of vertices and E is a collection of edges
◦ V = {1, 2, …n} and E = {(i1, j1), …, (im, jm)}
◦ |V| = n vertices and |E| = m edges
◦ ik [1, n] and k [1, m]
Randomly input a starting vertex X and
print the list of vertices “breadth-first
search” from X
Hint: using queue
50
EXERCISE (GRAPH)
Pseudo code 1
Initialize an array Mark[n] = {0}
2
Choose X: enqueue X into queue
while(Queue is not empty) 3
dequeue to a variable called y
Mark[y] = 1; 4
Print y 5
for all z adjacent to y & Mark[z] = 0 9
enqueue z
end-for 6
7
end-while
8
7 8
2 4
6
9 5 13
V = {1, 2, 3, 4, 5, 6, 7, 8, 9}
E = {(1, 3), (1, 4), (2, 4), (2, 9), (3, 5), (3, 6), (4, 5), (4, 7), (6, 8), (7, 8), (8, 9)} 51