Chapter Goals

• To become familiar with using vectors to collect objects
• To be able to access vector elements and resize vectors
• To be able to pass vectors to functions
• To learn about common vector algorithms

Using Vectors to Collect Data Items

• Example: Suppose you write a program that reads in a list of salary figures and prints out the list, marking the highest value, like this:
`320005400067500290003500080000highest value => 1150004450010000065000`
• All the values need to be read to find the highest one.
• If you know there are 10 inputs, you could use 10 variables salary1, salary2, ... , salary10. But you would have to write a lot of code 10 times to handle each variable.
• This technique becomes prohibitive as the list gets larger (100 salaries).
• A vector is a collection (a sequence) of data items of the same type.
`vector<double> salaries(10);`
• This vector holds 10 successive values of double type.

Syntax 9.1: Vector Variable Definition

`vector<type_name> variable_name;vector<type_name> variable_name(initial_size);`
 Example: `vector scores;vector staff(20);` Purpose: Define a new variable of vector type, and optionally supply an initial size.
• You must specify which slot (element, memory location) you want to use with the [] (subscript, index) operator.
`salaries[4] = 35000;`
• The number inside the brackets is called an index.
• Because salaries is a vector of double values, a slot such as salaries[4] can be used just like any variable of type double.
`cout << salaries[4] << "\n";`
• In C++, the slots (elements) of vectors are numbered starting at 0.

Vector Subscripts

Syntax 9.2: Vector Subscripts

`vector_expression[integer_expression]`
 Example: `salaries[i + 1]` Purpose: Access an element in a vector.
• Trying to access a slot that does not exist in the vector is an error.
`vector<double> salaries(10);cout << salaries[10]; /* COMMON ERROR! Legal subscripts are 0 until 9 */`
• The C++ standard implementation of vector generates no error message.
• If you make an index error, you silently read or overwrite another memory location.
• When a vector is defined without a size parameter, it is empty and can hold no elements.
`vector<double> salaries; /* no size given */salaries[0] = 35000; /* ERROR ! */`
• You can find the size vector by calling the size()member function.
`for(i = 0; i < salaries.size(); i++)   do something with salaries[i];`
• Using size is actually better than using a constant (so called magic number).
• The function push_back allows you to start out with an empty vector and grow the vector whenever another element is added.
`vector<double> salaries;. . . double s;cin >> s;. . .salaries.push_back(s);`
• The push_back member function resizes the vector by adding one element to its end.
• If you already know how many elements you need in a vector, you should specify that size when you define it.
• Another member function, pop_back, removes the last element of a vector, shrinking its size by one.
`salaries.pop_back(); /* Now salaries has size 9 */`
• The C++ standard (STL) defines many more useful functions for vectors, but we will use only size, push_back and pop_back.

Vector Parameters and Return Values

• Functions and procedures often have vector parameters.
• Example: This function computes the average of a vector of floating-point numbers.
`double average(vector<double> v){  if (v.size() == 0) return 0;   double sum = 0;   for (int i = 0; i < v.size(); i++) sum = sum + v[i];   return sum / v.size();}`
• average.cpp
• A vector can be passed by value or by reference.
• Pass by reference is used for modifying individual elements of the vector.
• Example: The function raises all values in the vector by the given percentage.
`void raise_by_percent(vector<double>& v, double p){  for (int i = 0; i < v.size(); i++)           v[i] = v[i] * (1 + p / 100);}`
• A function can return a vector.
• Example: Here is a function that collects all values that fall within a certain range.
`vector<double> between(vector<double> v, double low, double high){  vector<double> result;   for (int i = 0; i < v.size(); i++)      if (low <= v[i] && v[i] <= high) result.push_back(v[i]);   return result;}`
• between.cpp
• Example: Here is a function that collects the positions (indexes) of all matching values in a vector of integers.
`vector<int> find_all_between(vector<double> v, double low, double high){  vector<int> pos;   for (int i = 0; i < v.size(); i++)      if (low <= v[i] && v[i] <= high) pos.push_back(i);   return pos;}`

Removing and Inserting Elements

• How do you remove an element from a vector?
• If the order is not important, overwrite the element to be removed with the last element of the vector, then shrink the size of the vector.
`void erase(vector<string>& v, int pos){  int last_pos = v.size() - 1;   v[pos] = v[last_pos];   v.pop_back();}`
• erase1.cpp
• If the order matters, you must move all elements down by one slot (to the index 0), then shrink the size of the vector.
`void erase(vector<string>& v, int pos){  for (int i = pos; i < v.size() - 1; i++) v[i] = v[i + 1];   v.pop_back();}`

Removing and Inserting Elements (erase2.cpp)

• To insert an element in the middle of a vector, you must add a new element at the end of the vector and move all elements above (to the end of the vector) the insertion location up by one slot.
`void insert(vector<string>& v, int pos, string s){  int last = v.size() - 1;   v.push_back(v[last]);   for (int i = last; i > pos; i--) v[i] = v[i - 1];   v[pos] = s;}`
• Note that when you insert an element you start at the end of the vector, move that element up, then go to the one before that.

Parallel Vectors

• Example: Suppose you want to process a series of product data, and the display the product information, making the best value (with the best price/score ratio).
`               ACMA P600 Price: 995 Score75               ALaris Nx686 Price 798 Score 57               AMAX Powerstation 600 Price: 999 Score 75               AMS Infogold P600 Price: 795 Score: 69               AST PRemmia Price: 2080 Score: 80               Austin 600 Price: 1499 Score: 95best value =>  Blackship NX-600 Price 598 Score: 60               Kompac 690 Price: 695 Score: 60`
• One possibility is to create three vectors (names, price, scores) of the same length.
• These vectors are called parallel vectors because they must be processed together.
• Each slice - names[i], prices[i], scores[i] - contains data that needs to be processed together.

Parallel Vectors (bestval1.cpp)

• Parallel vectors become a headache in larger programs.
• Each vector must be the same length.
• Each slice is filled with values that belong together.
• Any function that operates on a slice must get several vectors as parameters.
• To remove parallel vectors, look at the slice and find the concept it represents. Make the concept into a class.
• Eliminate parallel vectors and replace them with a single vector of objects.