Previous Lecture Lecture 2 Next Lecture

Lecture 2, Tue 10/01

STL: Vectors, Iterators, Sets, and Maps

Standard Template Library

It’s really rare if a programming language provides all of the necessary tools to accomplish a task “out of the box”

These libraries usually come standard with the language

Implementing and maintaining libraries come with a cost

Since C++ isn’t a product of a large organization, and is kinda organized like opensource

Standard Libarary Containers

There are many implementations of containers.

std::Vector

# Makefile
CXX=g++

main: main.o
        ${CXX} -o main -std=C++11 main.o

clean:
        rm -f *.o main
// main.cpp
#include<vector>

using namespace std;

int main() {
	vector<int> v; // a vector containing int elements
return 0;
}

Under-the-hood, vectors are implemented using arrays and behave similar to arrays.

Adding to a vector example

// main.cp
#include<vector>

using namespace std;

template <class T>
void printVector(vector<T> &v) {
	for (int i = 0; i < v.size(); i++) {
		cout << "v[" << i << "] = " << v[i] << endl;

	// range-based for loop example
	// int index = 0;
	// for (int i : v) {
	// 	cout << "v[" << index << "] = " << i << endl;
	// }

	}
}

int main() {
	vector<int> v;
	for (int i = 0; i < 5; i++) // it could be any reasonable size…
		v.push_back(i);

	printVector(v);
	return 0;
}

Example

cout << v.at(4) << endl;
cout << v.at(5) << endl; // EXCEPTION THROWN
cout << v1[5] << endl; // JUNK

Other supported operations are:

cout << "v.front() = " << v.front() << endl;
cout << "v.back() = " << v.back() << endl;
v.pop_back();
printVector(v);

Vector Initialization

push_back() is one way to create elements in a vector. Though it’s not the only way

Example:

vector<int> v1(100); // initializes vector with 100 elements.
vector<int> v2(100, 1); //initializes vector with 100 elements = 1

Example creating a vector on the heap with a pointer reference to the vector contents on the heap

vector<int>* v = new vector<int>(10,1); // vector with 10 elements = 1
cout << v->size() << endl;
printVector(*v);

Iterators

Example

vector<string> v2;

v2.push_back("Hello.");
v2.push_back("My");
v2.push_back("name");
v2.push_back("is");
v2.push_back("Batman");

for (vector<string>::iterator i = v2.begin(); i < v2.end(); i++) {
	cout << *i << " "; // string value
	cout << i->size() << endl; // prints the size of the strings
}

In the above example, we’ve seen vector functions that deal specifically with iterators.

Example (Showing different ways to index elements using iterators):

vector<string>::iterator i = v2.begin();
cout << v2[4] << endl; 		// Batman
cout << i[4] << endl;		// Batman
cout << *(i + 4) << endl;	// Batman

In order to erase items in the vector, there is an erase method that requires iterators to do this

Example of erasing elements

// Removing 2nd index of the vector
// v2.erase(v2.begin() + 2); // remove "name"
// printVector(v2);

// Removing 1st and 2nd index - [1,3)
v2.erase(v2.begin() + 1, v2.begin() + 3);
printVector(v2);

Sets

Example

#include <set>

using namespaces std;

int main() {
	set<string> s;
	s.insert("Harry");
	s.insert("Hermione");
	s.insert("Ron");
	s.insert("Harry"); // duplicate (only stored once)
	s.insert("Snape");
	// print out the contents
	for (set<string>::iterator i = s.begin(); i != s.end(); i++) {
		cout << *i << endl;
	}
}

Finding an element in a set

Example

if (s.find("Harry") != s.end()) {
	cout << "Harry exists!" << endl; // prints this
} else {
	cout << "Harry DNE" << endl;
}

if (s.find("Hagrid") != s.end()) {
	cout << "Hagrid exists!" << endl;
} else {
	cout << "Hagrid DNE" << endl;	// prints this
}

Maps

Example

#include <map>
map<int, string> students; // mapping studentIDs to studentNames

// Use bracket notation for creation
students[0] = "Richert";
students[1] = "John Doe";
students[2] = "Jane Doe";
cout << "students[1] = " << students[1] << endl;

Example using find()

// Check if a student id exists
if (students.find(1) == students.end()) {
	cout << "Can’t find id = 1" << endl;
} else {
	cout << "Found student id = 1, Name = " << students[1] << endl;
}

Example using <string, double> types

map<string, double> stateTaxes;

stateTaxes["CA"] = 0.88;
stateTaxes["NY"] = 1.65;

if (stateTaxes.find("OR") == stateTaxes.end()) {
	cout << "Can't find OR" << endl;
} else {
	cout << "Found state OR" << endl;
}

Example between insert vs. []

#include <utility> // for std::pair

// ...

students.insert(pair<int, string>(2, "Chris Gaucho")); // does not replace
students[2] = "Chris Gaucho"; // replaces
cout << students[2] << endl;

Erasing using iterators

Example

// Erasing by iterator
map<int, string>::iterator p = students.find(2);
students.erase(p); // erases "Jane Doe"

// Erasing by key
students.erase(0); // erases "Richert"

// print out the entire map…
for (map<int, string>::iterator i = students.begin(); i != students.end(); i++) {
	cout << i->first << ": " << i->second << endl;
}