Categories
Computer Science / Information Technology Language: C++

Vectors

The vectors are sequence containers to store data of a similar type. Vectors represent arrays that can change in size. Just like arrays, vectors use contiguous storage locations for their elements, which means that their elements can also be accessed using offsets on regular pointers to their elements, and just as efficiently as in arrays. But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container.

Internally, vectors use a dynamically allocated array to store their elements. This array may need to be reallocated in order to grow in size when new elements are inserted, which implies allocating a new array and moving all elements to it. This is a relatively expensive task in terms of processing time, and thus, vectors do not reallocate each time an element is added to the container. Instead, vector containers may allocate some extra storage to accommodate for possible growth, and thus the container may have an actual capacity greater than the storage strictly needed to contain its elements (i.e., its size). 

Libraries can implement different strategies for growth to balance between memory usage and reallocations, but in any case, reallocations should only happen at logarithmically growing intervals of size so that the insertion of individual elements at the end of the vector can be provided with amortized constant time complexity.

Therefore, compared to arrays, vectors consume more memory in exchange for the ability to manage storage and grow dynamically in an efficient way.

Declaration

To use a vector in a C++ program, one needs to include the vector library:

#include <vector>

The syntax of the declaration of a vector is as follows:

vector <data_type> vector_var;

Where, data_type can be any valid primary, secondary or user-defined data type permitted by C++. The data type can be a vector itself.

Example:

vector <int> whole_numbers;

The above example just declares the vector but the size of the vector is 0. The size of the vector can also be mentioned at the time of declaration. The syntax for the same is as follows:

vector <data_type> vector_var (size);

Where size should be strictly an unsigned integer.

Example:

vector <int> whole_numbers (10);

The advantage of mentioning the size at the time of declaration is that it is efficient to allocate memory at compile time and also, all the 10 values of the vector whole_numbers in the above declaration will be initialised to 0. The vector library provides a method size() which returns the number of values the vector object holds.

Example 1
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector <int> whole_numbers;
    cout << "The size of the vector 'whole_numbers' is "
         << whole_numbers.size();
    return 0;
}

Output: The size of the vector ‘whole_numbers’ is 0

Conclusion: If the size is not mentioned, the default size is 0

Example 2
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector <int> whole_numbers (10);
    cout << "The size of the vector 'whole_numbers' is "
         << whole_numbers.size();
    return 0;
}

Output: The size of the vector ‘whole_numbers’ is 10

Conclusion: The vector gets declared and the mentioned size is allocated to the vector.

Example 3
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector <int> whole_numbers (10);
    cout << "The size of the vector 'whole_numbers' is "
         << whole_numbers.size() << endl;
    cout << "The elements in the vector are: ";
    for (size_t i = 0 ; i < whole_numbers.size() ; i++)
        cout << whole_numbers[i] << " ";
    return 0;
}

Output:

The size of the vector 'whole_numbers' is 10
The elements in the vector are: 0 0 0 0 0 0 0 0 0 0

Conclusion: If just the size is mentioned, all the values in the vector will be initialized to 0

Initialising vectors

Using initializer lists

When the values to be present in the vector are known at the time of declaration, the following syntax can be used:

Syntax:

vector <data_type> vector_var {value_1, value_2,..., value_n};
// Or
vector <data_type> vector_var = {value_1, value_2,..., value_n};
// Or
vector <data_type> vector_var = ({value_1, value_2,..., value_n});

Where the values being initialised are strictly of the type data_type.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector <char> vowels = {'a', 'e', 'i', 'o', 'u'};
    for (size_t i = 0 ; i < vowels.size() ; i++)
        cout << vowels[i] << " ";
    return 0;
}

Output: a e i o u

Conclusion: Vector initialisation using initialiser lists

Using constructor of vector container

When the value to be present in all n indices of the vector is known, one can use the following syntax:

vector <data_type> vector_var (len, val);

The above syntax declares a vector named vector_var of size len and all the indices will be initialized to val.

Example:

vector <int> max_marks (10, 50);

The above syntax declares a vector named max_marks of size 10 and initializes all 10 indices to the value 50.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector <int> whole_numbers (10, 10);
    cout << "The size of the vector 'whole_numbers' is "
         << whole_numbers.size() << endl;
    cout << "The elements in the vector are: ";
    for (size_t i = 0 ; i < whole_numbers.size() ; i++)
        cout << whole_numbers[i] << " ";
    return 0;
}

Output:

The size of the vector 'whole_numbers' is 10
The elements in the vector are: 10 10 10 10 10 10 10 10 10 10

Conclusion: If the size and the value is mentioned, all the values in the vector will be initialized accordingly.

Using another vector

A new vector can be initialised with another vector. All the values of the source vector will be deep copied to the newly declared vector. The following is the syntax:

vector <data_type> vector_var (src_vector);

Where the src_vector strictly contains the values of the same data_type as that of the new vector. Any changes made to vector_var are local to vector_var and don’t reflect in src_vector.

Accessing values of a vector

Using subscripts – [ ]

Accessing vector elements could be done similar to accessing array elements – through subscripts. The syntax to do so is as follows:

vector_var[index];

Where the index is strictly unsigned integer which should be between 0 and size - 1 inclusive.

Array accessing using the subscripts provides no bound checking. That is, the programmer can mention an index value greater than size - 1. This causes the return value to be garbage.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector <int> whole_numbers (10, 10);
    cout << whole_numbers[11];
    return 0;
}

Output: 0

Conclusion: The vector element access using subscript notation doesn’t provide bounds checking.

Using at() method

The vector library provides at() method for vector objects to fetch/modify the values in the vector object. The syntax for the same is as follows:

vector_var.at(index);

This behaves in a similar way as that of the subscript access but at() method provides bounds checking. That is, the value of the index should be strictly between 0 and size - 1. Else, the method throws an exception.

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector <int> whole_numbers (10, 10);
    cout << whole_numbers.at(11);
    return 0;
}

Output:

Error:
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 11) >= this->size() (which is 10)

Conclusion: at() method provides bound checking.

Methods of vector class

C++ provides a rich library of methods to use with vectors. They are listed and described in the below table. For an example, consider a vector named num.

MethodDescriptionReturn typeParameters
sizeReturn size of the vectorsize_tNone
max_sizeReturn the maximum size which the vector is capable of holdingsize_tNone
resizeChange sizevoid(int new_size, int initialisation_value)
initialisation_value is optional and by default is 0
capacityReturn size of allocated storage capacitysize_tNone
emptyTest whether the vector is emptybooleanNone
reserveRequests that the vector capacity is at least enough to contain ‘n’ elements.voidn
shrink_to_fitRequests the container to reduce its capacity to fit its size.voidNone
atAccess element at the specified indexThe data type of the vector elementsIndex value between 0 and size – 1 inclusive
frontAccess first elementThe data type of the vector elementsNone
backAccess last elementThe data type of the vector elementsNone
dataReturns a direct pointer to the memory array used internally by the vector to store its owned elements.Pointer to vector element data typeNone
assignAssigns new contents to the vector, replacing its current contents, and modifying its size accordingly.voidsize_t n: the new size of the vector
value: to fill the vector with
push_backAdd element at the endvoidElement of same data type as that of the vector
pop_backDelete the last elementvoidNone
insertInsert elementsAn iterator that points to the first of the newly inserted elements.Iterator position and value to be inserted
eraseRemoves from the vector either a single element (position) or a range of elements ([first_iterator, last_iterator))An iterator pointing to the new location of the element that followed the last element erased by the function call.Iterator to the element to be deleted or 2 iterators: one to the beginning and the other to the end
swapExchanges the content of the container by the content of x, which is another vector object of the same type. Sizes may differ.voidReference to another vector x
clearRemoves all elements from the vector (which are destroyed), leaving the container with a size of 0.voidnone
emplaceConstruct and insert elementIterator to the new element insertedIterator position to insert the new value and the new value
emplace_backConstruct and insert an element at the endvoidThe new value to insert
Vector class methods

2D Vectors

It is possible to create multi-dimensional vectors in C++. The syntax of the declaration of a 2D vector is as follows:

vector <vector <data_type>> vector_var;

Exercises

  1. Eleven integer values are entered from the keyboard. The first 10 are to be stored in a vector. Search for the 11th integer in the vector. Write a program to display the number of times it appears in the vector.
  2. Read the size of the vector and declare the vector with the size entered. Read the vector elements and also read a key value. Display the number of times the key has appeared in the vector.
  3. Implement the Selection Sort, Bubble Sort and Insertion sort algorithms on a set of 10 numbers using vectors.
  4. Read the size of the vector and declare the vector with the size entered. Read the vector elements and sort the array using selection sort, bubble sort and insertion sort.
  5. Implement the Sieve of Eratosthenes and print the first 100 prime numbers. The algorithm is as follows:
    1. Fill vector values[100] with numbers from 1 to 100.
    2. Starting with the second entry in the array, set all its multiples to zero.
    3. Proceed to the next non-zero element and set all its multiples to zero.
    4. Repeat step 3 till you have set up the multiples of all the non-zero elements to zero.
    5. After step 4, all the non-zero entries left in the array would be prime numbers, so print out these numbers.
  6. Write a program to copy the contents of one vector into another in reverse order.
  7. Write a program to check if a vector is symmetric. That is, in a vector array_id check if array_id[0] = array_id[n-1], array_id[1] = array_id[n-2] and so on, where n is the size of the vector. Statically initialize the array or take user input.
  8. Find the smallest number, the largest number, and an average of values in a vector of floating-point numbers.
  9. Write a function to find the norm of a matrix. The norm is defined as the square root of the sum of squares of all elements in the matrix.
  10. Write a program to read 10 coordinates. Each coordinate contains 2 floating-point values X and Y. Print the two farthest points and 2 nearest points in the vector.

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page