Функция reserve
(
n
)
устанавливает
минимальную емкость контейнера равной n
при условии, что n
не меньше текущего размера. Таким образом, для предотвращения лишних затрат
следует установить достаточно большую емкость контейнера функцией reserve
,
причем сделать это нужно как можно раньше – желательно сразу же после конструирования
контейнера.
Чтобы разобраться с этими тонкостями, рассмотрим пример (пример 3).
Пример 3
vector<int> v; // Создаем пустой вектор
cout<<"Пустой вектор"<<endl;
cout<<"Емкость вектора "<<v.capacity()<<"\nКоличество элементов"
<<v.size()<<endl;
ints = 0;
// Заполняем вектор
for (int i=1; i<=1000; ++i)
{ if(v.size()==v.capacity()) s++;
v.push_back(i);}
cout<<"\nПосле заполнения вектора"<<endl;
cout<<"Емкость вектора "<<v.capacity()<<"\nКоличество элементов" <<v.size()<<endl;
cout<<"Число перерасределения памяти = "<<s<<endl;
cout<<"\nДобавим в конец вектора еще 67 элементов"<<endl;
v.insert(v.end(),67,1);
cout<<"Емкость вектора "<<v.capacity()<<"\nКоличество элементов" <<v.size()<<endl;
Результат
Пустой вектор
Емкость вектора 0
Количество элементов 0
После заполнения вектора
Емкость вектора 1066
Количество элементов 1000
Число перераспределений памяти 18
Добавим в конец вектора еще 67 элементов
Емкость вектора 1599
Количество элементов 1067
Анализ
Как и ожидалось, в пустом векторе число элементов, как и его размер, равны нулю. В процессе заполнения вектора 18 раз произошло перераспределение памяти, т. е. 18 раз происходила процедура, опи-санная выше. В результате размер (емкость) вектора превысил коли-чество элементов в нем на 66 элементов. Предположим, что нам нужно добавить в вектор еще 67 элементов, т. е. необходимое количество элементов в векторе превышает его текущий объем всего на один элемент. В этом случае опять происходит перераспределение памяти и объем памяти увеличивается в 1,5 раза. Таким образом, вместо нужного объема 1067 мы получили 1599.
При известном, количестве элементов вектора возникшие труд-ности (большое количество перераспределений памяти и избыточный размер вектора) можно решить просто:
vector<int> v ;
v.reserve(1067);
Тогда число перераспределений памяти будет равно нулю, а емкость – 1067, т. е. равной количеству элементов. Но ведь вектор – это динамический массив и размеры массива заранее не известны. Тогда можно подстраховаться и зарезервировать заведомо больший размер вектора (например, v.reserve(2000)). А чтобы вектор не удержи-вал ненужную память (2000 – 1067), необходимо сократить емкость от максимальной (2000) до используемой в настоящий момент (1067). Подобное сокращение емкости обычно называется «сжатием по размеру». Это сжатие в векторе v можно выполнить с помощью оператора:
vector<int>(v).swap(v); (табл. 3).
Таблица 3
Операции присваивания для векторов
Операция |
Описание |
v1 = v2 |
Присваивает v1 все элементы v2 |
v.assign(n,elem) |
Присваивает n копий заданного элемента |
v.assign(v1.beg,v1.end) |
Присваивает элементы интервала [beg,end) |
v1.swap(v2) |
Меняет местами содержимое v1 и v2 |
Следующий пример показывает, как assign может быть использована для копирования одного вектора в другой.
Пример 4
vector<int> v1;
for( int i = 0; i < 10; i++ ) v1.push_back( i ); // Заполнение вектора
vector<int> v2;
// Копирование вектора v1 в вектор v2
v2.assign( v1.begin(), v1.end() );
for( int i = 0; i < v2.size(); i++ ) cout << v2[i] << " ";
Результат
0 1 2 3 4 5 6 7 8 9
В табл. 4 перечислены все операции прямого обращения к элементам векторов. Как принято в С и C++, первому элементу вектора соответствует индекс 0, а последнему – индекс size()-1. Таким образом, n-му элементу соответствует индекс n – 1.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.