Transcript PowerPoint

STL: C++ Standard Library
.
Main Ideas
General
purpose: generic data structures &
algorithms, templates
Flexibility: Allows for many combinations of
algorithm-container
Simple & uniform interface:
interface through templates (not inheritence)
Efficiency
Reference:
http://www.sgi.com/tech/stl/
Components
Containers:
data structures
vector, list, map, set, deque
Adaptors: high-level data structure
stack, queue, priority_queue
Iterators: allow access into containers
Algorithms: base algorithms
sort, copy, search, min, max, …
Streams: input/output
String
Quick Facts
Vector<T>
 Implements an array of objects of type T
 Allows random-access to array
 Can grow on as needed basis
Map<KeyT,ValueT>
 “Associative Array”: maps keys to values
 Implemented as balanced binary tree
Example I – ShapeManager revisited
#include <vector>
#include <iostream>
using namespace std;
class Shape {
public: virtual void draw() = 0;
virtual ~Shape() {};
};
class Circle : public Shape {
public:
void draw() { cout << "Circle::draw\n"; }
~Circle() { cout << "~Circle\n"; }
};
class Triangle : public Shape {
public: void draw() { cout << "Triangle::draw\n"; }
~Triangle() { cout << "~Triangle\n"; }
};
class Square : public Shape {
public:
void draw() { cout << "Square::draw\n"; }
~Square() { cout << "~Square\n"; }
};
Example I – ShapeManager revisited
typedef std::vector<Shape*> Container;
typedef Container::iterator Iter;
int main() {
Container shapes;
shapes.push_back(new Circle);
shapes.push_back(new Square);
shapes.push_back(new Triangle);
for(int k = 0;k < shapes.size();k++ )
shapes[i]->draw(); //use operator[]
for(Iter j = shapes.begin(); j != shapes.end(); j++)
delete *j; //use iterator and dereferencing
} ///:~
Example II – unique word counter
#include <string>
#include <fstream>
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[]) {
ifstream source(argv[1]);
string word;
set<string> words;
while(source >> word)
words.insert(word);
copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
cout << "Number of unique words:" << words.size() << endl;
} ///:~
Containers
Holds
copies of elements
Assumes Copy Ctor & operator =
The standard defines the interface, not the
implementation
Two main classes
 Sequential containers:
list, vector,....
 Associative containers:
map, multimap, set ...
Sequential Containers
Maintain
a linear sequence of objects
Types of operations
Access/insertion/deletion of
elements at the front/end of sequence
Random access to elements
Sequential Containers
list - a linked list of objects
 Efficient insertion/deletion in
front/end/middle
vector - an extendable sequence of objects
 Efficient insertion/deletion at end
 Random access
deque – double-ended queue
 Efficient insertion/deletion at front/end
 Random access
Sequential Container Interface
size(),
empty()
push_front(x), push_back(x)
front(), back()
pop_front(), pop_back()
vector & deque
operator[](int index)
Associative Containers
Maintain
a collection of keys
Requires order on keys (less-than operator)
Keys can be accessed based on their order
(Typical) Implementation:
red-black binary trees
O(log n) time for access/insert/delete
Associative Containers
Set
A set of unique keys
Map
Associate a value to key (associative array)
Unique value of each key
Multiset
Multimap
Same, but allow multiple values
Example
class Count {
int i;
public:
Count() : i(0) {}
void operator++(int) { i++;
}
int& val() { return i; }
};
#include <string>
#include <map>
#include <iostream>
#include <fstream>
using namespace std;
typedef map<string, Count> WordMap;
typedef WordMap::iterator WMIter;
int main(int argc, char* argv[]) {
ifstream in(argv[1]);
WordMap wordmap;
string word;
while(in >> word)
wordmap[word]++;
for(WMIter w = wordmap.begin(); w != wordmap.end(); w++)
cout << (*w).first << ": " << (*w).second.val() << endl;
} ///:~
Associative Containers & Order
Associative
containers use operator< as
default order
We can control order by using our own
comparison function
To understand this issue, we need to use
function object
Function Objects
A class that implements operator()
Advantages:
Use the template mechanism (class versus
function)
Enable accumulating information in the
function object
Example
template<class T>
class less {
public:
bool operator()(T& lhs, T& rhs)
{ return lhs < rhs; }
};
less<int> cmp; // declare
if( cmp(1,2) )
…
if( less<int>()(1,2) )
…
an object
Creates temporary
objects, and then
call operator()
Function Object Bases
Base
classes for the functions objects are
defined in STL.
These provide standard names for the
arguments and return types.
template<class T>
class less :
public binary_function<T, T, bool>
{
…
}
Function Object Bases
template< class Arg, class Res>
struct unary_function {
typedef Arg argument_type;
typedef Res return_type;
};
template< class Arg, class Arg2, class Res>
struct binary_function {
typedef Arg first_argument_type;
typedef Arg2 second_argument_type;
typedef Res return_type;
};
Using Comparators
template<class T, class Cmp = less<T> >
class set {
…
}
…
set<int> s1;
a new
set<int,less<int> > s2;// Creates
same type
MyComp object.
set<int,MyComp > s3;
Use given
MyComp object.
MyComp cmp;
set<int,MyComp > s4(cmp);
STL Iterators
Iterators
are allow to traverse sequences
Methods
 operator*
 operator++, and operator—
Different types of iterators - to support read,
write and random access
Containers define their own iterator types
Changing the container can invalidate the
iterator
Iterator Types
Output Input
Read
Write
Iteration
x = *i
x = *i
x = *i
x = *i
*i = x
*i = x
*i = x
++
++
++, --
==, !=
==, !=
==, !=
++,
+=,
==,
<=,
*i = x
++
Comparison
Output:
Forward Bi-directional Random
--, +, -,
-=
!=, <, >,
>=
write only and can write only once
Input: read many times each item
Forward supports both read and write
Bi-directional support also decrement
Random supports random access (just like C
pointer)
Iterators & Containers
Bidirectional iterators:
 list, map, set
Random access iterators:
vector, deque
Input/output/forward iterators:
iostreams
Iterators and Containers
T::iterator – iterator type for type T
begin() – front of the container
end() – element after last
Container C
…
Container::iterator i
for( i = C.begin(); i != C.end(); i++)
// do something with *i
Iterators & Streams
Can access iostreams through iterators:
istream_iterator<string> in(cin);
istream_iterator<string> endOfInput;
ostream_iterator<string> out(cout);
while( in != endOfInput )
{
string s = *in++;
*out++ = s;
*out++ = “ “;
}
see useStreamIterators.cpp
Sequence Adapters
Adapters
of basic containers
Very easy, but limited interface
stack<T,Seq>
provides push, pop, top, size and empty
queue<T,Seq>
also provides back
priority_queue<T,Seq,Cmp>
provides same interface as stack
uses a compare function object
Algorithms Overview
Sequence
operations
 Non modifying: for_each, find, count,
search, mismatch, equal
 Modifying: transform, copy, swap, replace,
fill, generate, remove, unique, reverse,
rotate, random_shuffle
Sorted
sequences operations
 sort, lower_bound, upper_bound,
equal_range, binary_search, merge,
includes, set_union, intersection,
difference, symmetric_difference
Algorithms
Most
STL algorithms works on sequences
Sequences are passed as two iterators:
 beginning element
 element one after last
p
q
sequence [p,q)
Algorithms
depend on iterator type
not on container type
Copy
template< class In, class Out>
Out copy(In first, In last, Out res)
{
while (first != last)
*res++ = *first++;
return res;
}
See useCopy.cpp
Non-modifying Sequence
Algorithms

In find(In first, In last, const T& val)
find the first occurence of val in the sequence

In find_if(In first, In last, Pred p)
find the first element satisfying p

I1 find_first_of(I1 f1, I1 l1, I2 f2, I2 l2)
find the first match between two sequences.

I1 search( I1 f1, I1 l1, I2 f1, I2 l2 )
search for the sequence f2...l2 inside f1..l1
Sorted Sequence Algorithms

sort(In first, In last[, class cmp])
find the first occurence of val in the sequence
In lower_bound(In first, In last,
T const & val[, class cmp])
find the first element not less than val
 bool binary_search(In first, In last,
T const & val[, class cmp])
check if val appears in the sequence
 Out merge( I1 f1, I1 l1, I2 f1, I2 l2,
Out out )

merge two sorted sequences and write the merged
sequence onto the output iterator out