# Maps, sets, etc.

We saw vectors previously. Vectors are part of the “Standard Template Library” (STL) — “standard” because vectors are part of every C++ installation, “template” because the vector class is a template class (you can put any type of thing in a vector, but you have to choose the type for each vector and stick with it).

There are several other “containers” in the STL, and they are designed to support much of the same functionality of vectors. First we’ll learn about maps.

## Maps

Maps are like vectors in that they are STL containers. However, while vectors only store single values, map store key-value pairs. Imagine you want to store word frequencies: each word (a string) is a key, and the frequency (an integer) is the value. We’d make such a map like this:

``````#include <map>
// ...
map<string, int> wordfreqs;
``````

Then, to add stuff to the map, we could use the `insert` function (which is also available for vectors) but what’s probably more natural is to use the `[]` syntax:

``````wordfreqs["the"] = 1503032;
``````

The `[]` syntax is “overloaded” by the map class; that means the map class has redefined what `[]` does (previously, we only used `[]` on arrays). The result of the above code is that a new key-value pair “the” and 1503032 is put into the map. If we later wanted to get at the value 1503032 (e.g. to print the value), we could just write `wordfreqs["the"]` as you might expect.

## Map iterators

In order to look at all the key-value pairs in a map, we need a way to “iterate” through the map. All the STL containers (vectors, maps, sets, etc.) have their own specific “iterator” types. To make an iterator, write the same “template type” as when you created the map, but then put `::iterator` after it, like so:

``````map<string, int>::iterator it;
``````

Now `it` can iterate through a map that has string-int key-value pairs. The iterator need not be named `it`, but that is very common. The iterator acts like a pointer to the elements of the container. The statement `++it` (or `it++`, which is less common) moves the iterator to the next element.

Here is how you use an iterator (for any STL container):

``````for(it = wordfreqs.begin(); it != wordfreqs.end(); ++it)
{
// ... (treat 'it' as a pointer)
}
``````

That `for` loop basically means: let `it` iterate through `wordfreqs`, starting at the beginning and stopping once it passes the end.

Because a map has key-value pairs, we have to use `first` and `second` to get to the key and value (respectively). So `it->first` is the key of some key-value pair, and `it->second` is the value. We change the iterator (`++it`) to point to the next key-value pair, until we run out of them.

Here is a complete example. Note that it also includes the `find` function, which works on any STL container, and returns an iterator. If the iterator equals the “end” of the `wordfreqs` map, then that means the key was not found in the map. If the returned iterator does not equal the end, then we can use the iterator to get the value for that key.

``````#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
map<string, int> wordfreqs;

wordfreqs["the"] = 1503032;
wordfreqs["and"] = 35234;
wordfreqs["irregardless"] = 2324;
wordfreqs["regardless"] = 605;
wordfreqs["irrespective"] = 82;

cout << "wordfreqs has " << wordfreqs.size()
<< " elements." << endl << endl;

// print words & freqs
map<string, int>::iterator it;
for(it = wordfreqs.begin(); it != wordfreqs.end(); ++it)
{
cout << "'" << it->first << "' appeared "
<< it->second << " times." << endl;
}

cout << endl;

// search for a key
map<string, int>::iterator pos;
cout << "Is 'irrespective' in the wordfreqs list?" << endl;
pos = wordfreqs.find("irrespective");
if(pos != wordfreqs.end())
{
cout << "Yes! Its frequency is "
<< pos->second << "." << endl;
}
else
{
cout << "No." << endl;
}

return 0;
}
``````

Here is the output:

```wordfreqs has 5 elements.

'and' appeared 35234 times.
'irregardless' appeared 2324 times.
'irrespective' appeared 82 times.
'regardless' appeared 605 times.
'the' appeared 1503032 times.

Is 'irrespective' in the wordfreqs list?
Yes! Its frequency is 82.
```

## Sets

Sets are just like vectors (store single values) but don’t keep repeats. Their usage is quite similar to maps and vectors (which is the point):

``````#include <iostream>
#include <string>
#include <set>
using namespace std;

int main()
{
string s;
set<string> words;

while(s != "quit")
{
cout << "Enter a word, or 'quit' to quit: ";
cin >> s;
if(s != "quit")
{
words.insert(s);
}
}

cout << endl;
cout << "You entered (without repeats):" << endl;
set<string>::iterator it;
for(it = words.begin(); it != words.end(); ++it)
{
// use it like a pointer to a string
cout << *it << endl;
}

return 0;
}
``````

Output:

```Enter a word, or 'quit' to quit: happy
Enter a word, or 'quit' to quit: happy
Enter a word, or 'quit' to quit: joy
Enter a word, or 'quit' to quit: joy
Enter a word, or 'quit' to quit: quit

You entered (without repeats):
happy
joy
```