8. Vectors

Up until now, you have been storing data (like numbers) by initializing a variable then setting it to a value (e.g. int a = 3;). However, with more complex projects, this is not efficient and feasible, as you would have thousands of variable names to remember and use.

For example, if a teacher wants to analyze students’ exam scores using C++ (maybe find some stats like the mean or median), using what we know, we’d have to initialize variables for each score entered:

int student_one = 50;

int student_two= 1;

int student_three = 99;

int student_four= 0;

and so on...

If you have a huge class, this is not only annoying to type in, but also annoying to use, as if you want Student 1’s score, then you’d have to type in student_one.  Imagine if you want to do calculations involving the whole class’s scores - you’d have to waste so much time typing “student_<number>” to use that student’s score. 

So, is there a better way of doing this? Yes - the answer is by using a vector (this is not the same as vectors you see in math). Put simply, a vector can be thought of like a chain or shelf, where each position or ‘hole’ can store something. The length of the vector (how many ‘holes’/positions) is up to you and depends on your needs.  Look at the sample vector below: 

You can probably guess that this vector stores the exam scores of all the students in the class. See that there are different ‘positions’ in the vector, one for each student. In each position, there is one number corresponding to that student’s score. In this case, what would be the length of the vector? It would be the number of students in the class.

There are a lot of different uses for vectors, as seen in the examples below.

Example 1: A vector of size 5 containing homework scores for a student (5 integers for 5 HWs)

Example 2: A vector of size 2 containing the number of passengers in the different classes for an airplane from Detroit to New York  (2 integers for 2 classes)

Example 3: A vector of size 5 containing the different prices (in $) for different tickets to a concert (5 integers for 5 types of tickets)

Vectors don’t have to contain integers - they can contain any data type that we learned about, such as strings, doubles, booleans and characters. However, each vector can only contain one data type (you can’t have a character in one position within a vector, and an integer in another position within the same vector).

Example 4: A vector of size 100 containing the different names of students in a UM freshman-year aerospace class (100 strings for 100 students)

Example 5: A vector of size 4 containing the different responses to a true/false survey completed by a respondent (4 booleans for 4 different questions)

So, the real question is … how do we implement vectors in C++?

The first thing we need to do if we want to use vectors is to include the vectors library. To do so, type #include <vector> in the first part of the code, before the int main () section. The vector library can be used along with other libraries like the iostream library. As before, using namespace std should still be there. 

After doing this, there are two ways you can initialize a vector.

Method 1: Known Number of Elements

Say that you know the exact number of elements (positions or ‘holes’) you want in the vector. For example, in example 1 above, you know for sure that there are 5 homeworks, so you want the vector to have 5 elements.

Suppose that you want to make a vector for the homeworks at the start of the term when you don’t have scores yet (i.e., you don’t have the scores like 100 and 97 yet). You can still initialize a vector, then edit it once you have the scores.  If you just want to initialize the vector but don’t have values for the different positions/spaces in the vector, you can initialize it like this:

As you can see, to initialize a vector, you need to start with vector<type> - the “type” is the type of data you want your vector to contain. In the case above, we have int there because we want to put homework scores (which are integers) into the vector. After typing this, “homeworks(5) means that the vector’s name is “homeworks” and there are 5 elements in the vector. By default, the vectors are not actually ‘empty’ - they are just filled with zeros. For bool vectors, the default is false.


Take a look at Example 5. How would we initialize a vector for this?

Example 5: A vector of size 4 containing the different responses to a true/false survey completed by a respondent (4 booleans for 4 different questions)

We want a vector of size 4 containing bool values and suppose that we want to name the vector “responses”. We would then initialize it like this:

In other words, the general format for initializing a vector of known size but unknown values is:

vector<type> name(size)

where “type” is the data type, “name” is the name of your vector (you decide) and “size” is the known size of your vector (number of elements)

However, suppose that you not only know the number of elements, but also the values for the elements, you can initialize the vector with the values there already. For example, if you decide to initialize the homework scores vector at the end of the semester, you already know the scores, so you can input it into the vector directly like this:

Note that the format is slightly different from before. If we know the values, we still need to write “vector<int>” to tell C++ we want a vector of ints, and we still tell C++ the name by typing “homework”. However, after the name, we don’t need the size - instead, you can just type an equals sign and type the values in the homework vector between { and }, separated by commas. This is because if you type in 5 integers (as in this case), C++ already knows that the size will be 5.

You can see below how to initialize different vectors depending on what we know. If we want to make the vector before we have the values (e.g., making homework vector at start of term or making survey response vector before interviewing people), we can do it by telling C++ the vector size, as in the first and third line below. However, if we know the values of the vector (e.g., we make a homework vector when we know our scores at the end of the term or the survey response vector after interviewing people), we can do it by directly entering the values, as in the second and fourth line below.

Note that “homeworks” and “homework” are two different vectors. Similarly, “responses” and “response” are two different vectors. “Homeworks” has default values of 0 for each element, while “homework” has the 5 different scores stored. “Responses” has the default value of false stored for each element, while “response” has the 4 different true/false values stored.

Method 2: Unknown Number of Elements

Say, for example, that we are trying to make a vector for a student’s homework scores. In Method 1, when we knew there were 5 homeworks (but didn’t have the scores yet), we did something like this:

However, if you don’t know how many homework assignments there will be (like at the start of the semester when you may not know yet), then there is a way to initialize vectors without their size:

This is an easier method to initialize vectors if you don’t know how much it’s going to contain (the size) - the only difference between this and the previous method is that we don’t put the size of the vector in the parenthesis after the name (no “(5)” here).

At this point, you might be thinking: I know how to initialize a vector but how do we use this vector and store data inside it? Here are a few things we can do:

If you have an existing vector, you can add an element to the end of the vector. The size of the existing vector doesn’t matter (it can be zero if you initialized it using method 2). To add an element to the end of the vector, type the vector name followed by a dot, followed by push_back with the value of the new element in parenthesis. Look at the example below - we first initialize a homework vector in the first line, then add two new scores, 88 and 90, to the vector using push_back(). We see that not only is the new value added, it makes the vector grow by 1 in size.

Be careful - remember that if you initialize a vector without values but only its size, when you push_back, it won’t ‘put’ the value in the first slot, but after the initialized zeros. In the example below, the first line initializes a vector of 5 zeros, so the push_back(80) adds a new element (the 6th element) and puts 80 there, instead of at the front. 

2. Delete an element at the end of a vector: pop_back()

To delete an element at the end of a vector, type the name of the vector followed by a period, then pop_back(). There is nothing in the parenthesis as C++ doesn’t need to know the value of the last element to delete the last element. Not only will the last value be ‘gone’, the vector’s size will also decrease by 1.

3. Find the size of the vector: size()

To find the size of a vector, type the vector name followed by “.size()” . Technically, the “.size()” doesn’t do anything to the vector like pop_back() and push_back() do, but it is useful because you can easily know the size of the vector. One use is that you can print the size of a vector to the console (see example below). However, remember that “homework.size()” is an integer, so you need to initialize it to an int.

4. Access an element of a vector at a given index (position): [ ]

You can get the value or change the value at a certain index (position) in the vector by using [ ]. The position of the element/value you want is called the index. Note that the start of the vector (first element) is index 0 (not index 1), the second element is index 1 (not index 2), and so on.

To get a value, you type: vectorname[index], where vectorname is the name of the vector and index is the index number. For example, in the example below, homework[0] gets the 1st value of the homework vector (100). Then, homework[4] gets the 5th value of the homework vector (96). As you can see, the index is the actual position you want shifted by 1 (imagine you start counting positions from 0 instead of 1).

We can also change values in a vector using the “[ ]”. To do so, you access a vector’s element using [ ], then assign it a value using the equals sign. In the example below, we change index 1 of homework (second position) first to 10, then to 30. As you can see, the cout statement at the last line then accesses the first index (second position) of homework (30) and prints it out.

Another way of editing a value in a vector is to use the value itself. Above, you saw how we could directly assign a new value to a certain index (homework[1]=10). In that case, you didn’t need to use the old existing value - the new value at index 1 would be 10 regardless of the existing value (97). If we want to assign a new value based on the existing value, we can use the [ ] twice. 

In the example below, we change the value at index 2 of homework by setting it equal to the existing value plus 10. This sounds weird, but if we say “homework[2]=homework[2]+10, it’s saying add 10 to homework[2]. If this still seems weird, think about it this way. What do we want to change? Homework[2], because that is on the left hand side of the equals sign. Then, what do we want to assign to homework[2], the thing we’re changing? We want to assign to it homework[2]+10, or in other words, the original value of homework[2] plus 10. Other operations like subtraction, division and multiplication also work. 

Activity:

You work as a check-in agent at Detroit Airport and it is your job to track how many people are on-board a Delta Airlines flight to New York. Suppose that originally, Delta Airlines offers 2 classes, First and Economy. There are 130 people in Economy and 5 people in First.


Once you have done this, refer to the solution below.