Vector¶
Vector Definition¶
A vector is mostly a data structure as it is usually language specific.
A vector can be sometimes be treated as an ADT, when focusing on the data organization and behaviors only. Implementations are ignored.
Vector: A sequential ADT, similar to list ADT with some specific behaviors
Behaviors
access by index
insert remove by index
add remove at the end
check size/empty
C++ std::vector¶
A C++ implementation of the Vector ADT
An STL container
#include <vector>
vector is a class template, not a type!
vector<int>
is a class typeBased on a dynamic array internally
fast access by indexing
slow erase/insert in the middle
may re-allocate memory when out of space (capacity)
create a larger array
duplicate/move all elements from existing array
delete the existing array
resize
Variable length allowed
Out-of-boundary check with
.at(n)
methodautomatic memory re-allocation
Methods
Constructors
default: empty vector
(n)
: vector of size n, default values(n, v)
: vector of size n, fill values as v(aVectorOfSameType)
: copy another vector, must be same base type{item1, item2, ...}
: fill items from index 0
Operator =
v1 = {1, 2, 3}
: initializer_list assignmentv1 = v2
: copy assignment
at()
can assign value like
v.at(0) = 10;
with boundary check. Triggers out_of_boundary exception
preferred over
[]
syntax
clear()
clear the contentempty()
check emptysize()
push_back()
push the value as the last element
does not return value
pop_back()
removes the last element
does not return value! Be careful! Many pop methods in other languages returns a value.
back()
returns the value of the last element
resize()
may or may not re-allocate memory
does not erase data if downsized
find()
find an element by value, returns an iteratorinsert()
requires the use of iteratorserase()
requires the use of iterators
Initialization¶
When the braces are used, the initialization will use the values as items. Must use parentheses when triggering other constructors.
vector<int> v{1, 2, 3, 4, 5}
size 5 vector with valuesvector<int> v = {1, 2, 3, 4, 5}
size 5 vector with values, preferred for sequence initializationvector<int> v(5)
size 5 vector with 0s,v{5}
will make a size 1 vectorvector<int> v(5, 1)
size 5 vector with 1s, warning:v{5, 1}
will make a size 2 vector insteadvector<int> v1(v)
make a copy of v
C++ Iterator Type (Extended reading)¶
In C++, an iterator is an object that enables traversal through the elements of a container, such as a vector, list, or map, without exposing the underlying implementation of the container. Iterators provide a consistent interface to access and modify the elements of a container, regardless of the specific container type. They allow for efficient manipulation of container elements by providing methods for moving between elements, accessing the value at the current position, and modifying the value at the current position. Iterators are an essential tool for generic programming in C++ and allow for efficient, type-independent algorithms to be written for a variety of container types.
A derived type of STL containers such as vector, list, map, etc.
e.g.
vector<int>::iterator
is used to iterate through a vector of int.May use
auto
to simplify the type declaration:auto it = v.begin();
Vector methods using iterator
begin()
returns an iterator pointing to the first elementend()
returns an iterator pointing to the element after the last elementerase(iterator)
removes the element at the iterator position and returns the iterator pointing to the next elementinsert(iterator, value)
inserts the value before the iterator position and returns the iterator pointing to the inserted element
Functions using iterators
find(begin, end, value)
returns an iterator pointing to the first element that matches the value in the range defined by a beginning iterator and an ending iterator. It return the end iterator if not found.
Example:
vector<int> v = {1, 2, 3, 4, 5}; vector<int>::iterator it = find(v.begin(), v.end(), 3); it = v.erase(it); // remove the element at the iterator position, returns // the iterator pointing to the next element
Passing vector around¶
As parameter
by-value (object duplication):
void func1(vector<int> vec);
read-only reference:
void func1(const vector<int> &vec);
by-reference (allow modifications of the actual parameter):
void func1(vector<int> &vec);
example:
1// Assume that the Patient class is ready for use 2// read data from a csv file and create the vector of Patient objects 3loadData(vector<Patient> &patients, string filename); 4 5class TextMenuApp { 6 vector<Patient> &patients; // takes a reference to avoid copy overhead 7 public: 8 TextMenuApp(vector<Patient> &patients): patients(patients) {} 9 void run(); 10 // ... 11}; 12 13int main() { 14 // Only one vector is created in the scope of the main function 15 // Its reference is passed around 16 vector<Patient> patients; 17 loadData(patients, "patients.csv"); 18 TextMenuApp app(patients); 19 app.run(); 20 return EXIT_SUCCESS; 21}
As returned value
return by value (object not necessary duplicated, some optimization will happen)
see the filter example
Algorithms¶
Works with all algorithms on arrays
change
arr[i]
tovec.at(i)
no longer need to pass a separate size variable
Particularly good for out-of-place algorithms with variable length output
filter type of algorithm, i.e. find all positive value in a vector:
1vector<int> positiveOnly(const vector<int> &v) { 2 vector<int> result; 3 for (int i = 0; i < v.size(); ++i) 4 if (v.at(i) > 0) 5 result.push_back(v.at(i)); 6 return result; 7}
Pitfalls¶
use [] rather than at()
int a = v.pop_back();
should beint a = v.back(); v.pop_back()
cout << v.length();
Wrong! There is no length() methodif (v.size() == 0)
this works but better useif (v.empty())
Extended Readings¶
Use
.emplace_back()
with object vectorUse for each loop with vectors