Show Lecture.STLContainers as a slide show.
CS253 STL Containers
Overview
- The most popular containers:
Attributes
Name | Key/Value | Insertion | Append | Search | Ordered |
string, vector | value | O(n) | O(1) | O(n) | no |
list, forward_list | value | O(1) | O(1) | O(n) | no |
[multi]set | value | O(log n) | | O(log n) | yes |
[multi]map | key/value | O(log n) | | O(log n) | yes |
deque | value | O(n) | O(1) | O(n) | no |
unordered_[multi]set | value | O(1) | | O(1) | oddly |
unordered_[multi]map | key/value | O(1) | | O(1) | oddly |
Popular methods
- Universal container methods:
- default ctor
- copy ctor
operator=
- ctor(iter, iter)
empty()
size()
/ max_size()
clear()
begin()
/ end()
/ cbegin()
/ cend()
- Popular container methods:
- ctor(n)
rbegin()
/ rend()
/ crbegin()
/ crend()
front()
/ back()
insert()
/ erase()
find()
/ count()
Popular types
- Universal types:
value_type
iterator
const_iterator
size_type
- Popular types:
key_type
reverse_iterator
const_reverse_iterator
string con = "The quick brown fox jumps over a lazy dog.";
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=42 The quick brown fox jumps over a lazy dog.
- This displays a std::string.
- After this, the same code will be shown, but using different
containers.
- Sure, we could have just said
cout << con;
since we’re using
a std::string, but but that won’t work for other container types.
string s = "The quick brown fox jumps over a lazy dog.";
vector<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=42 The quick brown fox jumps over a lazy dog.
We can’t initialize a vector directly from a C-style string,
so we put it into a C++ string, and initialize the vector
from that, using the two-iterator constructor.
string s = "The quick brown fox jumps over a lazy dog.";
array<char, 41> con;
for (size_t i=0; i<s.size(); i++)
con[i] = s[i];
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=41 The quick brown fox jumps over a lazy dog
A std::array is not a C array. However, it does have a size
fixed at compile time. Its storage is all on the stack, with no
dynamic memory allocation, so it’s as effecient as a C array. It has
typical STL container methods such as .size()
, .begin()
,
.end()
, etc.
It lacks the two-iterator ctor, perhaps due to its fixed size.
string s = "The quick brown fox jumps over a lazy dog.";
list<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=42 The quick brown fox jumps over a lazy dog.
A list is a doubly-linked list. It has a large storage overhead,
but insertion is cheap, and you can easily go forward & backward.
Unlike a vector, .push_back()
never causes reallocation.
string s = "The quick brown fox jumps over a lazy dog.";
forward_list<char> con(s.begin(), s.end());
for (auto c : con)
cout << c;
The quick brown fox jumps over a lazy dog.
A forward_list (formerly slist
) is a singly-linked list.
It has a large storage overhead, but insertion is cheap, and you can
easily go forward. Curiously, there is no forward_list::size()
.
string s = "The quick brown fox jumps over a lazy dog.";
deque<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=42 The quick brown fox jumps over a lazy dog.
A deque is a double-ended queue.
It’s like a vector, but you can easily push or pop from the
front or the back.
string s = "The quick brown fox jumps over a lazy dog.";
set<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=28 .Tabcdefghijklmnopqrsuvwxyz
A set is generally implemented as a binary tree. Hence, it is
sorted, has fairly large storage overhead, and has O(log n)
find/insertion/deletion times.
string s = "The quick brown fox jumps over a lazy dog.";
multiset<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=42 .Taabcdeefghijklmnoooopqrrsuuvwxyz
A multiset is like a set, but allows copies.
string s = "The quick brown fox jumps over a lazy dog.";
unordered_set<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=28 .gdyzlaspmjxfnworbkciuqv ehT
A unordered_set (formerly hash_set
), is a hash table
implementation like a set.
string s = "The quick brown fox jumps over a lazy dog.";
unordered_multiset<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
cout << c;
size=42 .gdyzlaaspmjxfnwoooorrbkciuuqv eehT
A unordered_multiset (formerly hash_multiset
), is a hash table
implementation like a multiset.
map example
map<string, double> gpa = {
{ "Jack", 3.998 },
{ "Russ", 4.20 },
{ "Wim", 3.92 },
{ "Craig", 2.0 }
};
for (auto p : gpa)
cout << p.first << " has a GPA of " << p.second << '\n';
cout << "Jack’s GPA is: " << gpa["Jack"] << '\n';
Craig has a GPA of 2
Jack has a GPA of 3.998
Russ has a GPA of 4.2
Wim has a GPA of 3.92
Jack’s GPA is: 3.998
- A
map<A,B>
is like a set<pair<A,B>>
, ordered by A
.
pair<A,B>
has public data members (😲)
.first
and .second
.