--- title: Vectors --- ## Vectors The C++ `vector` is one of the most used containers in C++. A container is a data structure that stores a collection of objects that can vary from being ordered(like `vector`!) to unordered(like `set`). All C++ containers have a different set of functions that allow you to access an object(s) in that collection, modify and loop over the elements in that data structure. Vectors are similar to ArrayLists in Java since you don't have to specify the length of the container. Compared to an array where you have to define how large it is, its size depends on its contents. `std::vector` is part of the C++ standard library (hence the prefix `std::`) and allows you to store contiguous data of the same data type. NOTE: **All objects within a vector must be of the same data type** The data type you store within a vector goes within angle brackets next to the vector keyword. For example, if you would like to store a collection of strings the vector would be `std::vector vector_name` *NOTE*: You must include the vector library whenever using vectors! `#include ` ### Vector Construction There are many convinent ways to construct a vector. Using an intializer list - where objects are listed inside a set of braces: `{ }` ```cpp std::vector a{1, 2, 3, 4, 5}; // a is a vector of 5 ints: 1, 2, 3, 4 and 5 std::vector b{"hello", "world"}; // b is a vector of 2 strings: "hello" and "world" std::vector v; // v is an empty vector ``` Constructing it from another vector (this is known as a copy construction) ```cpp std::vector a{1.0, 2.0, 3.0}; std::vector b(a); // b is a vector of 3 doubles: 1.0, 2.0 and 3.0 ``` Initializing it with the same element: ```cpp std::vector a(100, -1); // a is a vector of 100 elements all set to -1 ``` ### Vector Iterators Iterators can be thought of as pointers specifically used for navigating containers (such as vectors). The most important iterators are `begin()` and `end()`. `begin()` returns a pointer to the first item in a vector whereas `end()` points to one position after the last item in a vector. As such looping through a vector can be done as : ```cpp std::vector vec{1, 2, 3}; for(auto vec_it = vec.begin(); vec_it != vec.end(); it++){ // since vec_it is a pointer and points to the memory address of the item // inside the vector, vec_it must be dereferenced using '*' std::cout << *it << '\n'; } /* Output 1 2 3 */ ``` ### Modifying a Vector Pushing items to a vector: ```cpp std::vector vec; // constructs an empty vector for (int i = 0; i < 10; i = i + 2){ vec.push_back(i); } // vec now holds [0, 2, 4, 6, 8] ``` Inserting an item in a particular position is slightly different. The C++ vector insert function works on iterators. It will insert the given item one position before the given iterator. ```cpp std::vector vec{3, 400, 12, 45}; auto iter = vec.begin() + 2; // iter now points to '12' vec.insert(iter, 38); // inserts '38' before '12' // vec: [3, 400, 38, 12, 45] ``` ### Element Access The standard library provides different functions for accessing particular elements in your vector. ```cpp std::vector a{"test", "element", "access"}; std::string first_item = a.front(); // gets the first item of the vector ("test") std::string last_item = a.back(); // gets the last item in the vector ("access") // To get an element at a specific index (remember: vector indices start at 0) std::string second_item = a.at(2); // gets "element" // OR std::string second_item = a[2]; // gets "element" ``` ### Looping over elements in a `vector` Looping over elements in a C++ `std::vector` is pretty different from looping over elements in a vector in JavaScript or Ruby. Due to C++ being a thin abstraction of C, you can only loop over elements using these nifty little variables called iterators to access each element. Iterators often come in the form of pointers which are variables that store the memory address of another variable. You can learn more about pointers [here](https://www.tutorialspoint.com/cplusplus/cpp_pointers.htm). However, because iterators act as pointers (or vice-versa), in order to see what they point to, you need to dereference it into a variable of the appropirate type. How do we do this? HERE. WE. GO! ```cpp std::vector a{"test", "element", "access"}; for(auto it = v.begin(); it != v.end(); it++) { //notice use of auto keyword cout<<*it< v; //Iterator delcaration for the above vector will correspond to std::vector::iterator it; ``` Using the iterator to print elements of the vector using for loop ```cpp for(it=v.begin(); it!=v.end(); ++it) //std::vector::begin and std::vector::end return iterator pointing to first and last element of the vector respectively. cout<<*it; ``` ### Iterating Through a Vector There are different ways to iterate through a vector and access its contents. The following forms are equivalent, the first one involves using a range-based expression (since C++11), the second one uses iterators, and the last one is a index-based iteration ``` cpp #include #include // First declare the vector std::vector myVector{1, 2, 3, 4, 5}; // a is a vector of 5 ints: 1, 2, 3, 4 and 5 // Using a range based loop (since C++11) for(int element : myVector ){ // Reads like "for every element in myVector" std::cout << "The element is " << element << std::endl; } // Using an iterator std::vector::iterator it; // Declare the iterator for(it = myVector.begin(); it != myVector.end(); ++it){ std::cout << "The element is " << *it << std::endl; // Dereference the iterator to access its data } // Using indices for(std::vector::size_type i = 0; i != myVector.size(); i++){ std::cout << "The element is " << myVector[i] << std::endl; // Dereference the iterator to access its data } ``` ### Sorting A Vector In Ascending Order Sorting a vector based on ascending order can be done with the help of Sort() in C++. ``` cpp #include #include #include using namespace std; int main(){ vector v{ 10, 5, 82, 69, 64, 70, 3, 42, 28, 0 }; sort(v.begin(), v.end()); cout << "Vector Contents Sorted In Ascending Order:\n"; for(int e : v){ cout << e << " "; } return 0; } ``` In C++11, you can also sort with lambda function, which can be useful. ```cpp11 #include using namespace std; int main() { vector v {3, 1, 2}; sort(v.begin(), v.end(), [] (int i, int j) -> bool { return i < j; } ); cout << "Vector Contents Sorted In Ascending Order:\n"; for (int e : v) cout << e << " "; return 0; } ``` ### Sorting Vector In Descending Order Sorting Vector in descending order can be done with the help of third argument namely greater() in Sort() in C++. ``` cpp #include #include #include using namespace std; int main(){ vector v{ 10, 5, 82, 69, 64, 70, 3, 42, 28, 0 }; sort(v.begin(), v.end(), greater()); cout << "Vector Contents Sorted In Ascending Order:\n"; for(int e : v){ cout << e << " "; } return 0; } ``` You can also sort in descending using lamda like the one above.