STL - Gordon College

advertisement
STL Overview
Prof. Brinton
Gordon College
1
Standard Template Library (STL)
•
•
Part of ISO-OSI Standard C++ Library 1998
Object oriented programming is about reuse
– STL has many reusable components
– Divided into
1. Containers - manage collections of objects
2. Iterators - step through the elements of collections
3. Algorithms - used to process the elements of
collections
2
Introduction to Containers
•
Three types of containers
1. sequence containers - ordered collections
vector, deque, list
2. associative containers - sorted collections
set, multiset, map, multimap
3. container adapters
•
•
Stacks, queues, priority queues
Near-containers - similar to containers, without all the
capabilities
– C-like arrays
– string
– bitset - for maintaining sets of 1/0 flag values
– valarray - high-speed mathematical vector operations
The containers have similar functions
3
Introduction to Containers
• vector
• deque
• list
direct access to any element
rapid insertion at front or back
direct access to any element
rapid insertion and deletion anywhere
• set
• multiset
• map, multimap
rapid lookup, no duplicates
rapid lookup, duplicates
store key/value pairs
• stack
• queue
• priority_queue
last-in-first-out
first-in-first-out
highest priority element is first
4
Introduction to Containers
• Common member functions of all STL containers:
constructors, destructors
assignment, all comparison operators
swap
empty
max_size
size
• Use if(c.empty()) not if(c.size() == 0)
5
Introduction to Iterators
• Iterators are similar to pointers
– point to element in a container
– iterator operators uniform for all containers
• * dereferences, ++ advances pointer
• container.begin() returns iterator pointing to first element
• container.end() returns iterator pointing after last element
it
for(it = c.begin();
it != c.end();
it++)
{
*it…
}
6
Iterator Categories
• Bidirectional iterators
– Iterate in 2 directions: p++ or p-– list, set, multiset, map, multimap
– Use != instead of < or > in loops
• Random access iterators
– Have all properties of bidirectional iterators
– Can also perform random access
• +, -, <, >
– vector, deque, strings
7
Constness of Iterators
• Examples
vector<int>::iterator it = v.begin();
vector<int>::const_iterator cit = v.begin();
*cit = 24; // does not compile
*it = 24; // ok
void fct(const vector<int>& v)
{
vector<int>::iterator it;
it = v.begin(); // does not compile
}
8
Constness of Iterators
• Examples (Fixed)
vector<int>::iterator it = v.begin();
vector<int>::iterator cit = v.begin();
*cit = 24; // ok
*it = 24; // ok
void fct(const vector<int>& v)
{
vector<int>::const_iterator it;
it = v.begin(); // ok
}
9
Iterator Adapters
• Everything that behaves like an iterator is an iterator
– Insert iterator (inserters)
– Stream iterator - allow you to use a stream as a source or dest of an
algorithm.
– Reverse iterators
• Example:
list<Point>::reverse_iterator r1 = L.rbegin(),
r2 = L.rend();
10
Iterator Adapters
vector<int> coll;
back_insert_iterator<vector<int> > iter(coll);
*iter = 1; iter++;
*iter = 2; iter++;
*iter = 3;
PRINT_ELEMENTS(coll);
back_inserter(coll) = 44;
back_inserter(coll) = 55;
PRINT_ELEMENTS(coll);
coll.reserve(2*coll.size());
copy (coll.begin(), coll.end(), // source
back_inserter(coll));
// destination
PRINT_ELEMENTS(coll);
Results:
123
1 2 3 44 55
1 2 3 44 55 1 2 3 44 55
11
Introduction to Algorithms
• STL algorithms used generically across containers:
– operate on elements indirectly through iterators
– often operate on sequences of elements defined by pairs
of iterators
– algorithms often return iterators, such as find()
– premade algorithms save programmers time and effort
12
Sequence Containers
• Three sequence containers
– vector - based on arrays
– deque - based on arrays
– list - robust linked list
13
vector Sequence Container
• vector
–
–
–
–
–
#include <vector>
data structure with contiguous memory locations
use the subscript operator []
used when data must be sorted and easily accessible
when memory exhausted
• allocates a larger, contiguous area of memory
• copies itself there
• deallocates the old memory
– has a random access iterator
14
vector Sequence Container
• Declarations
– vector <type> v;
– vector <type> v(7812);
– template <class It>
vector<type> v(It begin, It end);
– type - int, float, Point, whatsoever
• Iterators:
– vector<type>::const_iterator it;
vector<type>::iterator it = v.begin();
*(it1 + 5) = 34;
15
vector Sequence Container (II)
• vector functions, for vector object v
v.push_back(value) - add element to end
v.size() - current size of vector
v.capacity() - how much vector can hold before reallocation
v.reserve(n) - allow vector to avoid reallocation
v.insert( pointer, value ) - inserts value before pointer.
16
vector Sequence Container (III)
• vector functions and operations
v.erase( pointer )
• remove element from container
v.erase( pointer1, pointer2 )
• remove elements starting from pointer1 and up to (not
including) pointer2.
v.clear()
• erases entire container.
v[elementNumber] = value;
• assign value to an element
v.at[elementNumber] = value;
• as above, with range checking
• throws out_of_bounds exception
17
list Sequence Container
• list container
– #include <list>
– efficient insertion/deletion anywhere in container
– doubly-linked list
– bidirectional iterators
• There exists also a non-standard slist
– singly-linked list
– forward iterator
18
list Sequence Container (II)
• list functions for listObject and otherObject
listObject.sort()
• sorts in ascending order
listObject.splice(iterator, otherObject);
• inserts values from otherObject before location of iterator
listObject.merge(otherObject)
• removes otherObject and inserts it into listObject, sorted
listObject.unique()
• removes duplicate elements
listObject.swap(otherObject);
•
exchange contents
listObject.assign(iterator1, iterator2)
• replaces contents with elements in range of iterators
listObject.remove(value)
• erases all instances of value
19
deque Sequence Container
• deque ("deek") - double-ended queue
– #include <deque>
– indexed access using []
– efficient insertion/deletion in front and back
– non-contiguous memory: "smarter" pointers
• same basic operations as vector
– adds push_front / pop_front - insertion/deletion at
beginning of deque
20
Associative Containers
• Associative containers
– provide direct access to store and retrieve elements via keys
(search keys)
• 4 types: multiset, set, multimap and map
– keys in sorted order
– multiset and multimap allow duplicate keys
– multimap and map allow keys and associate values
21
Excursion: Function Objects
template <class T>
struct less
{
bool operator()(const T& lhs, const T& rhs) const
{
return lhs < rhs;
}
};
less<int> is_smaller;
if(is_smaller(45, 34)){..}
22
multiset Associative Container
• multiset - fast storage, retrieval of keys
– allows duplicates
• Ordering by comparator function object
less<type> - sorts keys in ascending order
multiset< int, less<int> > integers;
• CGAL comparator function objects
typedef CGAL::Cartesian<double> K;
multiset< K::Point_2, K::Compare_xy_2 >
points;
23
multiset Associative Container (II)
• Functions for multiset object msObject
– msObject.insert(value) - inserts value
– msObject.find(value) - returns iterator to first instance
of value, or msObject.end()
– msObject.lower_bound(value)- returns iterator to first
location of value
– msObject.upper_bound(value)- returns iterator to
location after last occurrence of value
– for a pair object p
p = msObject.equal_range(value)
• sets first and second to lower_bound and upper_bound
for a given value
24
set Associative Container
• set
– implementation identical to multiset
– unique keys - duplicates ignored and not inserted
– supports bidirectional iterators (but not random access)
– #include <set>
25
map Associative Container
• map
– fast storage/retrieval of unique key/value pairs
– #include <map>
– one-to-one mapping (duplicates ignored)
– use [] to access values
for map<int, double> M;
M[30] = 4000.21;
sets the value of key 30 to 4000.21
– if subscript not in map, creates new key/value pair
– Efficiency remark: Use insert to insert, operator[] to update
26
Non Standard Associative Container
• hash_(multi)set, hash_(multi)map
–
–
–
–
Not part of the standard, but provided by some STLs
REALLY fast storage/retrieval of unique key/value pairs
Based on hashing and not on binary trees
No order, but provide iterators
27
Container Adapters
• container adapters: stack, queue, priority_queue
–
–
–
–
–
not first class containers
do not support iterators
do not provide actual data structure
programmer can select implementation of the container adapters
have member functions push() and pop()
28
stack Adapter
• stack
–
–
–
–
insertions and deletions at one end
last-in-first-out data structure
implemented with vector, list, and deque (default)
#include <stack>
• Declarations
stack<type, vector<type> > myStack;
stack<type, list<type> > myOtherStack;
stack<type> anotherStack;
29
queue Adapter
• queue - insertions at back, deletions at front
– first-in-first-out data structure
– implemented with list or deque
– #include <queue>
• Functions
–
–
–
–
push(element) - (push_back) add to end
pop(element) - (pop_front) remove from front
empty() - test for emptiness
size() - returns number of elements
• Example:
queue <double> values;
values.push(1.2);
values.push(3.4);
values.pop();
//create queue
// values: 1.2
// values: 1.2 3.4
// values: 1.2
30
priority_queue Adapter
• insertions in sorted order, deletions from front
– implemented with vector or deque
– highest priority element always removed first
• heapsort puts largest elements at front
• less<T> by default, programmer can specify another
• Functions
–
–
–
–
push - (push_back then reorder elements)
pop - (pop_back to remove highest priority element)
size
empty
31
Algorithms
• Before STL
– class libraries were incompatible among vendors
– algorithms built into container classes
• STL separates containers and algorithms
– easier to add new algorithms
– not member functions of containers, global functions that operate
with iterators (reduces the amount of code)
• Not necessarily intuitive…not all combinations possible.
– General fundamental services on containers:
• Searching
• Sorting
• Copying
• Reordering
• Modifying
• Numeric processing
32
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
Algorithms Example
int main()
{
vector<int> coll;
vector<int>::iterator pos;
coll.push_back(2); coll.push_back(5); coll.push_back(4); coll.push_back(1);
coll.push_back(6); coll.push_back(3);
254163
pos = min_element (coll.begin(), coll.end());
cout << "min: " << *pos << endl;
pos = max_element (coll.begin(), coll.end());
cout << "max: " << *pos << endl;
}
1
6
sort (coll.begin(), coll.end());
123456
pos = find (coll.begin(), coll.end(), 3);
reverse (pos, coll.end());
126543
33
Algorithms
•
Ranges
pos = min_element (coll.begin(), coll.end());
•
Multiple Ranges
if (equal (coll1.begin(), coll1.end(), coll2.begin()) { … }
Algorithm Categories:
1.
2.
3.
4.
5.
6.
7.
Nonmodifying - count, for_each, min_element…
Modifying - copy, transform, merge, replace, fill…
Removing - remove, unique…
Mutating - reverse, rotate, random_shuffle…
Sorting - sort_heap, make_heap, sort, …
Algorithms for Sorted Ranges - binary_search, merge, …
Numeric - accumulate, inner_product, …
34
Non-Modifying Algorithm: for_each
void print (int elem)
{
cout << elem << ' ';
}
int main()
{
vector<int> coll;
INSERT_ELEMENTS(coll,1,9);
// call print() for each element
for_each (coll.begin(), coll.end(), print);
cout << endl;
}
35
Modifying Algorithm: copy
{
vector<int> coll1;
list<int> coll2;
INSERT_ELEMENTS(coll1,1,9);
copy (coll1.begin(), coll1.end(),
back_inserter(coll2));
copy (coll2.begin(), coll2.end(),
ostream_iterator<int>(cout," "));
cout << endl;
copy (coll1.rbegin(), coll1.rend(),
coll2.begin());
}
36
Modifying Algorithm: unique
int source[] = { 1, 4, 4, 6, 1, 2, 2, 3, 1, 6, 6, 6, 5, 7, 5, 4, 4 };
int sourceNum = sizeof(source)/sizeof(source[0]);
list<int> coll;
copy (source, source+sourceNum, back_inserter(coll));
list<int>::iterator pos;
pos = unique (coll.begin(), coll.end());
copy (coll.begin(), pos, ostream_iterator<int>(cout," " // source));
cout << "\n\n";
copy (source, source+sourceNum, coll.begin());
coll.erase (unique (coll.begin(), coll.end(),
greater<int>()), coll.end());
37
accumulate, transform
• list<int> L(..);
int sum = accumulate(L.begin(), L.end(),
0, plus<int>());
• transform(istream_iterator<Point>(cin),
istream_iterator<Point>(),
ostream_iterator<double>(cout),
mem_fun_ref(Point::x));
39
Basic Searching Algorithms
• find(iterator1, iterator2, value)
– returns iterator pointing to first instance of value
• find_if(iterator1, iterator2, function)
– like find, but returns an iterator when function returns true.
• binary_search(iterator1, iterator2, value)
– searches an ascending sorted list for value using a binary search
40
Sorting Algorithms
• sort(begin, end)
• partial_sort(begin, begin+N, end)
– finds first N and sorts them
• nth_element(begin, begin+N, end)
– finds first N, not sorted
• partition(begin, end, function)
– splits in two intervals
• stable_sort, stable_partition
• Remarks
– All take optionaly a comparison function
– std::sort is faster than clib sort
41
equal, mismatch,
lexicographical_compare
• Functions to compare sequences of values
• equal
– returns true if sequences are equal (uses ==)
– returns false if of unequal length
equal(iterator1, iterator2, iterator3);
– compares sequence from iterator1 up to iterator2 with the
sequence beginning at iterator3
– Containers can be of different types
42
fill, fill_n, generate, generate_n
•
STL functions, change containers.
•
fill - changes a range of elements (from iterator1 to iterator2) to
value
– fill(iterator1, iterator2, value);
•
fill_n - changes specified number of elements, starting at iterator1
– fill_n(iterator1, quantity, value);
•
generate - like fill, but calls a function for value
– generate(iterator1, iterator2, function);
•
generate_n - like fill_n, but calls function for value
– generate(iterator1, quantity, value)
43
swap, iter_swap and swap_ranges
• swap(element1, element2) - exchanges two values
swap( a[ 0 ], a[ 1 ] );
• iter_swap(iterator1, iterator2) - exchanges the values to
which the iterators refer
• swap_ranges(iterator1, iterator2, iterator3) - swap the
elements from iterator1 to iterator2 with the elements
beginning at iterator3
44
copy_backward, merge, unique, reverse
•
copy_backward(iterator1, iterator2, iterator3)
– copy the range of elements from iterator1 to iterator2 into
iterator3, but in reverse order.
•
merge(iter1, iter2, iter3, iter4, iter5)
– ranges iter1-iter2 and iter3-iter4 must be sorted in ascending
order.
– merge copies both lists into iter5, in ascending order.
•
unique(iter1, iter2) - removes duplicate elements from a sorted list,
returns iterator to new end of sequence.
•
reverse(iter1, iter2)- reverses elements in the range of
iter2.
iter1 to
45
Remove does (not) Remove
• Member function:
L.remove(Point(0,0));
• Algorithm moves at end:
list<Point> L(istream_iterator<Point>(cin),
istream_iterator<Point>());
list<Point>::iterator eit;
eit = remove(L.begin(), L.end(), Point(0,0));
L.erase(eit, L.end());
46
Other Features of the STL
•
•
•
•
•
Streams
strings, wide strings
locales (for internationalization)
numerical
valarray
47
References
• N.M. Josuttis, The C++ Standard Library, Addison-Wesley
2001
48
Download