a != b

Transcript

a != b
C++ STL
Standard Template Library:
a brief tutorial
Most part of the material is taken from
http://www.sgi.com/tech/stl/
Copyright © 1993-2006 Silicon Graphics, Inc. All rights reserved.
Overview & key concepts
CONTAINERS
ALGORITHMS
ITERATORS
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
2
Overview
 The STL is a generic library, meaning
that its components are heavily
parameterized: almost every component
in the STL is a template
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
3
Containers - I
 Classes whose purpose is to contain
other objects







vector
list
deque
set & multiset
map & multimap
hash_set & hash_multiset
hash_map & hash_multimap
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
4
Containers - II
 Each container is a template, and can be
instantiated to contain any type of object.
vector<int> v(3);
// Declare a vector of 3 elements.
v[0] = 7;
v[1] = v[0] + 3;
v[2] = v[0] + v[1]; // v[0] == 7, v[1] == 10, v[2] == 17
 You can use a vector<int> in much the same way
as you would use an ordinary C array, without
managing dynamic memory allocation by hand.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
5
Algorithms - I
 A large collection of algorithms are
available to manipulate the data stored
in containers.
reverse(v.begin(), v.end());
7
// v[0] == 17, v[1] == 10, v[2] ==
 You can reverse the order of elements in a
vector, for example, by using the reverse
algorithm.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
6
Algorithms - II
 Note that:
 reverse is a global function, not a member
function.
 reverse takes two arguments rather than
one: it operates on a range of elements,
rather than on a container.
 The reason is that reverse, like other STL
algorithms, is decoupled from the STL
container classes, i.e. can be used not only
to reverse elements in vectors, but also to
7
reverse elements in lists.
Algorithms - III
 reverse can be used even on C arrays.
double A[6] = { 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 };
reverse(A, A + 6);
for (int i = 0; i < 6; ++i)
cout << "A[" << i << "] = " << A[i];
 This example uses a range, just like the
example of reversing a vector
 the first argument to reverse is a pointer to the
beginning of the range
 the second argument points one element past the
8
end of the range.
Iterators - I
 In the C vector examples the range is
expressed using double*, what about
v.begin() and v.end() of the vector<int>
example?
 They are iterators, a generalization of
pointers.
 Pointers themselves are iterator, and this
is the reason why C vector example
works
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
9
Iterators - II
 Declaration
vector<int>::iterator myIterator;
 Thus the type returned by v.begin() and
v.end() is vector<int>::iterator, because v is
a vector<int>
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
10
Iterators - III
 Iterators are the mechanism that makes it possible
to decouple algorithms from containers: algorithms
are templates, and are parameterized by the type
of iterator, so they are not restricted to a single
type of container.
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T&
value) {
while (first != last && *first != value) ++first;
return first;
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
11
Iterators - IV
 First and last are declared to be of type
InputIterator, and InputIterator is a template
parameter. That is, there isn't actually any type
called InputIterator: when you call find, the
compiler substitutes the actual type of the
arguments for the formal type parameters
InputIterator and T.
 If the first two arguments to find are of type int*:
int* find(int* first, int* last, const int& value) {
while (first != last && *first != value) ++first;
return first;
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
12
Concepts - I
 What is the set of types that may
correctly be substituted for the formal
template parameter InputIterator?
 int* or double* - YES
 int or double - NO
 [find uses the expression *first, and the
dereference operator makes no sense for an
object of type int or of type double]
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
13
Concepts - II
 find implicitly defines a set of requirements on
types, and that it may be instantiated with any
type that satisfies those requirements.
 Whatever type is substituted for InputIterator
must provide certain operations:
 comparing two objects of that type for equality,
 incrementing an object of that type
 dereferencing an object of that type to obtain the
object that it points to
 ...
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
14
Concepts - III
 we call such a set of type requirements a
concept, and we call this particular
concept InputIterator.
 We say that a type conforms to a
concept, or that it is a model of a
concept, if it satisfies all of those
requirements.
 For example int* is a model of InputIterator
because int* provides all of the operations
that are specified by the InputIterator
requirements.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
15
Concepts - IV
 Concepts are not a part of the C++
language but ...
 ... are an extremely important part of
the STL.
 Using concepts makes it possible to write
programs that cleanly separate interface from
implementation:
 the author of find only has to consider the
interface specified by the concept InputIterator,
rather than the implementation of every possible
type that conforms to that concept.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
16
Refinements of concepts - I
 InputIterator imposes very few requirements
 an InputIterator must support a subset of pointer
arithmetic (it must be possible to increment it
using prefix and postfix operator++), but need
not support all operations of pointer arithmetic.
 Some algorithms require that their arguments
satisfy additional requirements.
 reverse, for example, must be able to decrement
its arguments as well as increment them
 In terms of concepts, we say that reverse's
arguments must be models of
BidirectionalIterator rather than InputIterator
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
17
Refinements of concepts - I
InputIterator
OutputIterator
ForwardIterator
Refinements
BidirectionalIterator
RandomAccessIterator
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
18
There is more in STL...
 A few other concepts (e.g. Assignable)
 Allocators
 Function objects
 ...
Have a look at SGI web site to know more
about them!
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
19
More on containers - I
 A Container is an object that stores other
objects (its elements), and that has
methods for accessing its elements.
 In particular, every type that is a model
of Container has an associated iterator
type that can be used to iterate through
the Container's elements.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
20
More on containers - II
 There is no guarantee that the elements
of a Container are stored in any definite
order; the order might, in fact, be
different upon each iteration through the
Container.
 Nor is there a guarantee that more than
one iterator into a Container may be
active at any one time.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
21
Types associated to containers
 Value type
X::value_type
The type of the object stored in a container.
 Iterator type
X::iterator
The type of iterator used to iterate through a
container's elements. The iterator's value
type is expected to be the container's value
type. A conversion from the iterator type to
the const iterator type must exist. The
iterator type must be an InputIterator
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
22
Types associated to containers
 Const iterator type X::const_iterator
A type of iterator that may be used to
examine, but not to modify, a container's
elements
 Distance type
X::difference_type
A signed integral type used to represent the
distance between two of the container's
iterators
 Size type X::size_type
An unsigned integral type that can represent
any nonnegative value of the container's
distance type
23
Notations
 X
A type that is a model of Container
 a, b Object of type X
 T
The value type of X
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
24
Valid expressions and what
return
 a.begin()
iterator if a is mutable, const_iterator otherwise
 a.end()
iterator if a is mutable, const_iterator otherwise
 a.size()
size_type
 a.max_size()
size_type
 a.empty()
bool
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
25
Semantic of expressions
 X(a)
X().size() == a.size(). X() contains a copy of each
of a's elements
 X b(a)
b.size() == a.size(). b contains a copy of each of
a's elements
 b=a
b.size() == a.size(). b contains a copy of each of
a's elements
 a.~X()
Each of a's elements is destroyed, and memory
allocated for them (if any) is deallocated
26
Semantic of expressions
 a.begin()
Returns an iterator pointing to the first element
in the container
a.begin() is either dereferenceable or past-theend. It is past-the-end if and only if a.size() ==
0
 a.end()
Returns an iterator pointing one past the last
element in the container.
a.end() is past-the-end.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
27
Semantic of expressions
 a.size()
Returns the size of the container, that is, its
number of elements
a.size() >= 0 && a.size() <= max_size()
 a.max_size()
Returns the largest size that this container can
ever have
a.max_size() >= 0 && a.max_size() >= a.size()
 a.empty()
Equivalent to a.size() == 0. (But possibly faster.)
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
28
Complexity guaranties
 The copy constructor, the assignment operator,
and the destructor are linear in the container's
size
 begin() and end() are amortized constant
time
 size() is linear in the container's size
 max_size() and empty() are amortized
constant time. If you are testing whether a
container is empty, you should always write
c.empty() instead of c.size() == 0. The two
expressions are equivalent, but the former may
be much faster
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
29
An important note
 The fact that the lifetime of elements
cannot exceed that of of their container
may seem like a severe restriction, but...
 ... pointers and iterators are objects and
they may be stored in a container. The
container, in that case, "owns" the
pointers themselves, but not the objects
that they point to.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
30
Forward Container
 A Forward Container is a Container whose
elements are arranged in a definite order: the
ordering will not change spontaneously from
iteration to iteration
 The requirement of a definite ordering allows
the definition of element-by-element equality
and of lexicographical ordering
 Iterators into a Forward Container satisfy the
ForwardIterator requirements
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
31
Valid expressions for Forward C.
 a == b
and a != b
 a < b and a > b
 a <= b and a >= b
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
32
Reversible Container
 A Reversible Container is a Forward
Container whose iterators are
BidirectionalIterators.
 It allows backwards iteration through the
container.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
33
New associated types
 X::reverse_iterator
A Reverse Iterator adaptor whose base iterator
type is the container's iterator type.
Incrementing an object of type
reverse_iterator moves backwards through the
container: the Reverse Iterator adaptor maps
operator++ to operator--
 X::const_reverse_iterator
A Reverse Iterator adaptor whose base iterator
type is the container's const iterator type
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
34
Valid expressions for Reverse C.
 a.rbegin()
Equivalent to X::reverse_iterator(a.end()).
a.rbegin() is dereferenceable or past-the-end.
It is past-the-end if and only if a.size() == 0
 a.rend()
Equivalent to X::reverse_iterator(a.begin())
a.end() is past-the-end
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
35
Random Access Container
 A Random Access Container is a
Reversible Container whose iterator type
is a RandomAccessIterator
 It provides amortized constant time
access to arbitrary elements.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
36
Valid expressions for Random Access C.
 a[n]
0 <= n < a.size()
 The semantic is that a[n] returns the nth
element from the beginning of the
container.
 Complexity guarantee: the run-time
complexity of element access is
amortized constant time.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
37
Sequence
 A Sequence is a variable-sized Forward
Container whose elements are arranged
in a strict linear order
 It supports insertion and removal of
elements.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
38
Notation






X Sequence type
a, b Object of type X
T The value type of X
t Object of type T
p, q Object of type X::iterator
n Object of a type convertible to
X::size_type
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
39
Main expressions and semantic
 a.insert(p, t)
p must be a valid iterator in a
Must be true that a.size() < a.max_size()
A copy of t is inserted before p
a.size() is incremented by 1
 a.insert(p, n, t)
p must be a valid iterator in a
Must be true that n >= 0
Must be true that a.size() + n <= a.max_size()
n copies of t are inserted before p
a.size() is incremented by n
40
Main expressions and semantic
 a.erase(p)
p must be a dereferenceable iterator in a
Destroys the element pointed to by p and
removes it from a
a.size() is decremented by 1
 a.clear()
Equivalent to a.erase(a.begin(), a.end())
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
41
Front Insertion Sequence
 A Front Insertion Sequence is a
Sequence where it is possible to insert
an element at the beginning, or to
access the first element, in amortized
constant time
 Front Insertion Sequences have special
member functions as a shorthand for
those operations
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
42
Expressions for Front Insertion S.
 a.front()
!a.empty()
Equivalent to *(a.begin())
 a.push_front(t)
Equivalent to a.insert(a.begin(), t)
a.size is incremented by 1
a.front() is a copy of t.
 a.pop_front()
!a.empty()
Equivalent to a.erase(a.begin())
a.size() is decremented by 1.
43
Back Insertion Sequence
 A Back Insertion Sequence is a Sequence
where it is possible to append an
element to the end, or to access the last
element, in amortized constant time
 Back Insertion Sequences have special
member functions as a shorthand for
those operations
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
44
Expressions for Back Insertion S.
 a.back()
!a.empty()
Equivalent to *(--a.end())
 a.push_back(t)
Equivalent to a.insert(a.end(), t)
a.size is incremented by 1
a.back() is a copy of t
 a.pop_back()
!a.empty()
Equivalent to a.erase(--a.end())
a.size() is decremented by 1
45
Container classes
 Finally, we have a look to the real
classes!
 Sequences





vector
deque
list
slist
bit_vector
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
46
Vector
 A vector is a Sequence that supports random
access to elements, constant time insertion and
removal of elements at the end, and linear time
insertion and removal of elements at the
beginning or in the middle.
 The number of elements in a vector may vary
dynamically
 Memory management is automatic
 Vector is the simplest of the STL container
classes, and in many cases the most efficient
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
47
Example
vector<int> V;
V.insert(V.begin(), 3);
assert(V.size() == 1 && V.capacity() >= 1 &&
V[0] == 3);
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
48
Notes on memory reallocation
 Memory will be reallocated automatically
if more than capacity() - size() elements
are inserted into the vector
 Reallocation does not change size(), nor
does it change the values of any
elements of the vector. It does, however,
increase capacity(), and it invalidates
any iterators that point into the vector
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
49
Notes on memory reallocation
 It is possible to manually reallcate
memory using the function reserve()
 The main reason for using reserve() is
efficiency: if you know the capacity to which
your vector must eventually grow, then it is
usually more efficient to allocate that memory
all at once rather than relying on the automatic
reallocation scheme
 The other reason for using reserve() is so that
you can control the invalidation of iterators
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
50
Deque
 A deque is very much like a vector: it is a
sequence that supports random access to
elements, constant time insertion and removal
of elements at the end of the sequence, and
linear time insertion and removal of elements in
the middle
 The main difference from vector is that deque
also supports constant time insertion and
removal of elements at the beginning of the
sequence
 Additionally, deque does not have any
capacity() and reserve(), and does not provide
51
any of the guarantees on iterator validity
Example
deque<int> Q;
Q.push_back(3);
Q.push_front(1);
Q.insert(Q.begin() + 1, 2);
Q[2] = 0;
// The values in Q are 1 2 0
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
52
List
 A list is a doubly linked list
 It is a Sequence that supports both
forward and backward traversal, and
(amortized) constant time insertion and
removal of elements at the beginning or
the end, or in the middle
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
53
Example
list<int> L;
L.push_back(0);
L.push_front(1);
L.insert(++L.begin(), 2);
// The values in Q are 1 2 0
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
54
Slist
 An slist is a singly linked list: a list where
each element is linked to the next
element, but not to the previous element
 It is a Sequence that supports forward
but not backward traversal, and
(amortized) constant time insertion and
removal of elements
 If you do not need backward traversal,
then slist may be more efficient than list
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
55
Associative containers - I
 An Associative Container is a variablesized Container that supports efficient
retrieval of elements (values) based on
keys
 It supports insertion and removal of
elements, but differs from a Sequence in
that it does not provide a mechanism for
inserting an element at a specific
position
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
56
Associative containers - II
 As with all containers, the elements in an
Associative Container are of type
value_type. Additionally, each element in
an Associative Container has a key, of
type key_type
 In some Associative Containers, Simple
Associative Containers, the
value_type and key_type are the same:
elements are their own keys. In others,
the key is some specific part of the
value.
57
An important note
 Since elements are stored according to
their keys, it is essential that the key
associated with each element is
immutable
 In Simple Associative Containers this means
that the elements themselves are immutable,
while in other types of Associative Containers,
such as Pair Associative Containers, the
elements themselves are mutable but the part
of an element that is its key cannot be modified
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
58
Sorted associative Containers
 A Sorted Associative Container is a type of
Associative Container
 Sorted Associative Containers use an
ordering relation on their keys; two keys are
considered to be equivalent if neither one is less
than the other. (If the ordering relation is caseinsensitive string comparison, for example, then
the keys "abcde" and "aBcDe" are equivalent.)
 the complexity for most operations is never
worse than logarithmic, and elements are
always sorted in ascending order by key.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
59
Set - I
 Set is a Sorted Associative Container
that stores objects of type Key
 Set is a Simple Associative Container,
meaning that its value type, as well as
its key type, is Key
 It is also a Unique Associative
Container, meaning that no two
elements are the same
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
60
Set - II
 The elements of a set are always sorted
in ascending order
 Inserting a new element into a set does
not invalidate iterators that point to
existing elements
 Erasing an element from a set also does
not invalidate any iterators, except, of
course, for iterators that actually point to
the element that is being erased
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
61
Example - I
struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
62
Example - II
int main() {
const int N = 6;
const char* a[N] = {"isomer", "ephemeral", "prosaic",
"nugatory", "artichoke", "serif"};
const char* b[N] = {"flat", "this", "artichoke",
"frigate", "prosaic", "isomer"};
set<const char*, ltstr> A(a, a + N);
set<const char*, ltstr> B(b, b + N);
set<const char*, ltstr> C;
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
63
Example - III
cout << "Set A: ";
copy(A.begin(), A.end(), ostream_iterator<const
char*>(cout, " "));
cout << endl;
cout << "Set B: ";
copy(B.begin(), B.end(), ostream_iterator<const
char*>(cout, " "));
cout << endl;
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
64
Example - IV
cout << "Union: ";
set_union(A.begin(), A.end(), B.begin(), B.end(),
ostream_iterator<const char*>(cout, " "),
ltstr());
cout << endl;
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
65
Example - V
cout << "Intersection: ";
set_intersection(A.begin(), A.end(), B.begin(),
B.end(),
ostream_iterator<const char*>(cout, " "),
ltstr());
cout << endl;
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
66
Multiset
 Multiset is a Sorted Associative Container
that stores objects of type Key
 Multiset is a Simple Associative
Container, meaning that its value type,
as well as its key type, is Key
 It is also a Multiple Associative
Container, meaning that two or more
elements may be identical
 It similar to the set except for the
previous characteristic
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
67
Example - I
int main()
{
const int N = 10;
int a[N] = {4, 1, 1, 1, 1, 1, 0, 5, 1, 0};
int b[N] = {4, 4, 2, 4, 2, 4, 0, 1, 5, 5};
multiset<int> A(a, a + N);
multiset<int> B(b, b + N);
multiset<int> C;
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
68
Example - II
set_difference(A.begin(), A.end(), B.begin(),
B.end(), inserter(C, C.begin()));
cout << "Set C (difference of A and B): ";
copy(C.begin(), C.end(),
ostream_iterator<int>(cout, " "));
cout << endl;
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
69
Map
 Map is a Sorted Associative Container
that associates objects of type Key with
objects of type Data
 Map is a Pair Associative Container,
meaning that its value type is
pair<const Key, Data>
 It is also a Unique Associative Container,
meaning that no two elements have the
same key
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
70
Example - I
struct ltstr
{
bool operator()(const char* s1, const char*
s2) const
{
return strcmp(s1, s2) < 0;
}
};
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
71
Example - II
int main()
{
map<const char*, int, ltstr> months;
months["january"] = 31;
months["february"] = 28;
months["march"] = 31;
months["april"] = 30;
...
months[“december”]=31;
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
72
Example - III
cout << "june -> " << months["june"] << endl;
map<const char*, int, ltstr>::iterator cur = months.find("june");
map<const char*, int, ltstr>::iterator prev = cur;
map<const char*, int, ltstr>::iterator next = cur;
++next;
--prev;
cout << "Previous (in alphabetical order) is " << (*prev).first <<
endl;
cout << "Next (in alphabetical order) is " << (*next).first << endl;
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
73
Multimap
 ultimap is a Sorted Associative Container
that associates objects of type Key with
objects of type Data
 multimap is a Pair Associative Container,
meaning that its value type is
pair<const Key, Data>
 It is also a Multiple Associative
Container, meaning that there is no limit
on the number of elements with the
same key.
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
74
Example - I
 given the ltstr as before ...
int main() {
multimap<const char*, int, ltstr> m;
m.insert(pair<const char* const, int>("a", 1));
m.insert(pair<const char* const, int>("c", 2));
m.insert(pair<const char* const, int>("b", 3));
m.insert(pair<const char* const, int>("b", 4));
m.insert(pair<const char* const, int>("a", 5));
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
75
Example - II
cout << "Number of elements with key a: " << m.count("a") << endl;
cout << "Number of elements with key b: " << m.count("b") << endl;
cout << "Number of elements with key c: " << m.count("c") << endl;
cout << "Elements in m: " << endl;
for (multimap<const char*, int, ltstr>::iterator it = m.begin();
it != m.end(); ++it)
cout << " [" << (*it).first << ", " << (*it).second << "]" << endl;
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
76
Hashed associative containers
 A Hashed Associative Container is an Associative
Container whose implementation is a hash table
 The elements of a Hashed Associative Container are
not guaranteed to be in any meaningful order; in
particular, they are not sorted
 The worst case complexity of most operations on
Hashed Associative Containers is linear in the size of
the container, but the average case complexity is
constant time
 for applications where values are simply stored and
retrieved, and where ordering is unimportant,
Hashed Associative Containers are usually much
faster than Sorted Associative Containers
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
77
Hashed associative containers
 Hashed associative containers are not
part of the STL, but an extension
commonly available (recent version of
gcc, Visual C++ ecc...)
 hash_set & hash_multiset
 hash_map & hash_multimap
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
78
Example of hash_set
struct eqstr
{
bool operator()(const char* s1, const char*
s2) const
{
return strcmp(s1, s2) == 0;
}
};
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
79
Example of hash_set
void lookup(const hash_set<const char*, hash<const
char*>, eqstr>& Set, const char* word) {
hash_set<const char*, hash<const char*>,
eqstr>::const_iterator it = Set.find(word);
cout << word << ": "
<< (it != Set.end() ? "present" : "not present")
<< endl;
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
80
Example of hash_set
int main() {
hash_set<const char*, hash<const char*>, eqstr> Set;
Set.insert("kiwi");
Set.insert("plum");
Set.insert("apple");
lookup(Set, "mango");
lookup(Set, "apple");
lookup(Set, "durian");
}
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
81
Algorithms
Non mutating
Mutating
Sorting
Numeric
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
82
Non mutating algorithms
 InputIterator find(InputIterator first, InputIterator
last, const EqualityComparable& value);
 InputIterator find_if(InputIterator first,
InputIterator last, Predicate pred);
 count(InputIterator first, InputIterator last,
const EqualityComparable& value);
 count_if
 pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1
last1, InputIterator2 first2);
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
83
Mutating algorithms
 copy
 replace
 remove
 unique
 reverse
 random_shuffle
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
84
Sorting algorithms
 sort
 partial_sort
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
85
Numeric algorithms
 accumulate
 inner_product
 partial_sum
 adjacent_difference
Gabriele Monfardini - Corso di Ingegneria del Software a.a. 2007-2008
86