В языке C++ стандартный класс vector из библиотеки STL представляет собой динамический массив:
он хранит элементы подряд в памяти, как обычный массив, но при этом может автоматически менять свой размер.
В задачах vector используется очень часто и практически всегда удобнее обычного массива.
Для использования vector нужно подключить заголовочный файл c вот такой строкой:
#include <vector>
Объект vector всегда хранит элементы одного и того же типа. Запись
vector<int> a;
означает «динамический массив целых чисел». В угловых скобках < > указывается тип элементов:
vector<int> — массив целых чисел;vector<long long> — массив 64-битных целых;vector<double> — массив чисел с плавающей точкой;vector<string> — массив строк и т.д.
Нельзя создать vector, в котором часть элементов целые числа, а часть строки. Тип должен быть одинаковым для всех элементов.
Такая строка создаст пустой vector, в который потом можно добавлять элементы:
vector<int> a; // пустой vector<int> без элементов
Такой vector имеет размер 0, то есть он пока не хранит ни одного элемента.
Если заранее известно, сколько элементов нужно хранить, удобнее сразу создать vector нужного размера:
int n = 10;
vector<int> a(n); // vector из n целых чисел
В этом случае создается массив длины n, все элементы которого проинициализированы значениями по умолчанию:
int, long long, double) это 0;bool — false;string — пустая строка "".Расширение пустого вектора является немного более долгой операцией чем постепенное его увеличение, потому если вы заранее знаете нужный вам размер, то лучше сразу создать его нужной длины.
Можно сразу задать не только размер, но и начальное значение всех элементов:
int n = 5;
vector<int> a(n, 7); // 5 элементов, все равны 7
Обращение к элементам vector полностью совпадает с обращением к элементам обычного массива.
Индексация начинается с 0.
vector<int> a(5); // элементы: a[0], a[1], a[2], a[3], a[4]
a[0] = 10;
a[1] = 20;
int x = a[0] + a[1]; // x = 30
Важно: допустимыми индексами являются числа от 0 до a.size() - 1.
Обращение к элементу с индексом вне этого диапазона (например, a[-1] или a[5] при длине 5)
приводит к неопределенному поведению программы и может вызвать ошибку.
Метод size() возвращает текущее число элементов в vector:
vector<int> a(5);
cout << a.size() << endl; // выведет 5
a.push_back(42);
cout << a.size() << endl; // теперь размер 6
Тип возвращаемого значения — целое беззнаковое число, но в олимпиадном коде обычно можно просто писать
int n = a.size();, если размер массива гарантированно не превышает диапазона int.
Часто по условию задачи сначала задается число n — количество элементов, а затем следуют сами элементы.
Пример ввода:
5
1 3 5 7 9
Программа для чтения такого массива с помощью vector:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin >> n; // читаем количество элементов
vector<int> a(n); // создаем vector нужного размера
for (int i = 0; i < n; ++i) {
cin >> a[i]; // читаем i-й элемент
}
// дальше можно работать с массивом a
return 0;
}
Чтобы вывести все элементы vector, используют обычный цикл:
for (int i = 0; i < n; ++i) {
cout << a[i] << " ";
}
cout << endl;
Метод push_back(x) добавляет элемент x в конец vector. Размер увеличивается на 1.
vector<int> a; // пустой vector
a.push_back(10); // a: [10]
a.push_back(5); // a: [10, 5]
a.push_back(7); // a: [10, 5, 7]
Метод back() возвращает ссылку на последний элемент vector.
vector<int> a;
a.push_back(3);
a.push_back(7);
a.push_back(5);
int last = a.back(); // last = 5
Использовать back() можно только тогда, когда в vector уже есть хотя бы один элемент
(то есть a.size() > 0).
Метод pop_back() удаляет последний элемент vector. Размер уменьшается на 1.
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3); // a: [1, 2, 3]
a.pop_back(); // a: [1, 2]
a.pop_back(); // a: [1]
Нельзя вызывать pop_back() для пустого вектора (когда a.size() == 0).
Уже упомянутый метод size() возвращает количество элементов в vector. Часто используется в циклах:
for (int i = 0; i < a.size(); ++i) {
cout << a[i] << " ";
}
Метод resize(n) изменяет размер vector:
vector<int> a;
a.push_back(1);
a.push_back(2); // a: [1, 2], size = 2
a.resize(5); // a: [1, 2, 0, 0, 0], size = 5
a.resize(1); // a: [1], size = 1
Есть также форма resize(n, value), которая задает начальное значение для добавляемых элементов:
vector<int> a(2, 5); // a: [5, 5]
a.resize(4, 7); // a: [5, 5, 7, 7]