Контейнер vector

Объявление вектора

Вектор в STL - это аналог массива, контейнер, который позволяет осуществлять доступ к элементам по индексам. Вектор является шаблоном, и объявляется, как все остальные шаблоны.

Например, вектор целых чисел можно объявить так:

vector <int> A;

При таком создании вектор является "пустым", не содержащим элементов. Можно сразу же объявить вектор некоторого фиксированного размера, если задать конструктор, указав в конструкторе количество элементов вектора:

vector <int> A(n);

В этом случае значения элементов вектора будут нулевыми (а если элементами вектора являются не числа, а, например, строки или другие структуры данных, то элементы вектора будут принимать значения по умолчанию, то есть строки и вложенные вектора будут пустыми). При необходимости можно сразу же заполнить вектор некоторыми (одинаковыми), значениями, указав их в качестве второго параметра конструктора, например, для заполнения вектора значениями -1 можно его объявить так:

vector<int> A(n, -1);

Для использования контейнера vector необходимо подключить заголовочный файл vector:

#include<vector>

Обращение к элементам вектора

К элементам вектора можно обращаться по индексу, например, так: A[i].

Есть и другой способ обращения к элементу вектора с индексом i: использование метода at: A.at(i). Отличие метода at от обращения при помощи квадратных скобок в том, что при использовании метода at происходит проверка правильности индекса, и в случае выхода за границы вектора происходит ошибка исполнения. Это полезно при отладке программ.

При обращении к элементам вектора при помощи квадратных скобок корректность индекса не проверяется, и в случае выхода за границы вектора дальнейшее поведение программы может быть непредсказуемым.

Следует отметить, что работа с элементами вектора осуществляется медленнее, чем с элементами массива (даже при использовании квадратных скобок, то есть без проверки выхода за границы массива).

Помимо этого у вектора есть метод front(), возвращающий ссылку на первый элемент и метод back(), возвращающий ссылку на последний элемент вектора.

Изменение размера вектора

Размер вектора можно узнать при помощи универсального метода size(), возвращающего для всех контейнеров в STL их размер. Также есть метод empty(), возвращающий логическое значение (true, если вектор пустой).

Размер вектора можно изменить в любой момент, при помощи метода resize. У этого метода может быть один или два параметра. Вызов метода resize(n) изменяет размер вектора до n элементов (длина вектора может как уменьшится, так и увеличиться). Вызов метода resize(n, val) изменяет размер вектора до n элементов, и если при этом размер вектора увеличивается, то новые элементы получают значение, равное val.

Очень часто бывает полезно добавлять элементы в конец вектора по одному и удалять элементы из конца вектора по одному. Для добавления нового элемента, равного val, в конец вектора, используется метод push_back(val). Для удаления последнего элемента вектора используется метод pop_back() - он не возвращает значения.

Добавление элемента в конец вектора осуществляется в среднем за O(1). Это реализовано за счет того, что память для хранения элементов вектора выделяется "с запасом", то есть можно будет добавлять элементы по одному, пока не кончится запас памяти. Если запас памяти исчерпан, выделяется новая память, при этом "запас" размера вектора удваивается.

Очистить вектор можно при помощи метода clear().

Вставка и удаление элементов в середину вектора

Метод erase позволяет удалять из середины вектора один или несколько элементов. Этот метод работает с итераторами. Подробней про его использование можно прочитать в документации.

Метод insert позволяет вставлять в середину вектора новый элемент, или несколько равных элементов, или другой вектор, или фрагмент другого вектора. Этот метод также работает с итераторами и про его использование можно прочитать в документации.

Поскольку вставка и удаление элементов требуют сдвига других элементов вектора, эти операции имеют линейную сложность, то есть выполняются за время, пропорциональное длине вектора.

Присваивание и сравнение векторов

Содержимое одного вектора можно целиком скопировать в другой вектор при помощи операции присваивания: A = B.

Также вектора можно сравнивать на равенство и неравенство (A == B, A != B), и сравнивать их содержимое в лексикографическом порядке (A < B, A <= B, A > B, A >= B).

Создание многомерных векторов

Элементами вектора могут быть и другие вектора. Например, можно сделать вектор, каждый элемент которого представляет собой вектор целых чисел:

vector < vector <int> > a;

Тем самым, a[i] будет вектором целых чисел, а обращаться к j-му элементу вектора a[i] можно через a[i][j].

Чтобы создать двумерный вектор размером n×m можно внешний вектор объявить размером n, а затем в цикле изменить размер каждого вложенного вектора:

vector < vector <int> > a(n);

for (int i = 0; i < n; ++i)
    a[i].resize(m);

Но можно сделать это и в одну строку, если передать вторым параметром для конструктора вектора конструктор, который создает вектор целых чисел длины m:

vector < vector <int> > a(n, vector<int>(m));

Заметим, что размеры вложенных векторов могут изменяться и быть различными.

Также можно создавать вектор из стеков, очередей, деков, можно создавать трехмерные векторы и т.д.