Вектора в C++ (часть 3)

В этой статье и последующих, я постараюсь рассказать обо всех функция для работы с векторами. Поскольку вектора это динамический массив, то они могут иметь тот же тип, что и обычный массив, т. е. int, double, char и т. д. Сначала хотел порекомендовать, как правильно характеризовать вектора (т. е. присваивать им имена), например, есть такой код:

vector <int> array;
int array1[10];

Если Ваш код короткий (не превышает 50-100 строк), то Вы скорее всего в нем не запутаетесь, но если он больше 300 строк, то становится, очень тяжело в нем разобраться. Стоит осмысленно присваивать имена переменным. Поэтому я предлагаю инициализировать вектора примерно так:

vector <int> vecIntAge;
vector <string> vecStrName;

или, что-то подобное этому. Сначала должен идти префикс vec (если Вы используете list, deque… соответственно list, deque, можно сокращенно), потом тип и напоследок имя. Итак, теперь по теме векторов. Вектора можно представлять не только в виде одномерного массива, но также и в виде двухмерного массива или говоря иначе, матрицей. Пример:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<string>vecStr1{{'a','b','c','d'},///объявили вектор №1
                          {'e','f','g','h'},
                          {'i','j','k','l'}};
     cout<<"vecStr1 contains:\n";
     for(int y=0;y<vecStr1.size();++y)
     {
         for(int x=0;x<vecStr1[y].length();++x)
         {
             cout<<vecStr1[y][x]<<ends;
         }
         cout<<endl;
     }

    vector<string>vecStr2;///объявили вектор №2
    vecStr2.push_back("abcd");
    vecStr2.push_back("efgh");
    vecStr2.push_back("ijkl");
    cout<<endl;

    cout<<"vecStr2 contains: \n";
    for(int y=0;y<vecStr2.size();++y)
     {
         for(int x=0;x<vecStr2[y].length();++x)
         {
             cout<<vecStr2[y][x]<<ends;
         }
         cout<<endl;
     }
     return 0;
}

Пример работы программы:

CppStudio.com
vecStr1 contains: a b c d e f g h i j k l
vecStr2 contains a b c d e f g h i j k l

В строках 7-9 и 20 объявили вектора, только вектор vecStr1 инициализирован явно, а vecStr2 просто объявлен. В Строках 21-23 в конец вектора при помощи функции  push_back() добавляются строки. Как видите вывод вектора vecStr1 и vecStr2 осуществляется, так же как и вывод двумерного массива (матрицы), т. е. для доступа к любому элементу вектора нужно всего лишь указать его координаты по x и y. У векторов есть еще масса преимуществ перед «простыми» массивами, пример:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int arrayInt[10];
    vector <int> vecInt(10);///вектор размером на 10 элементов
    for(int i=0;i<10;++i)///заполнение массива из 10 элементов числом 1
    {
        arrayInt[i]=1;
    }

    vecInt.assign(10,1);///заполнение вектора из 10 элементов числом 1
    cout<<"Array contains: ";
    for(int i=0;i<10;++i) cout<<arrayInt[i]<<ends;
    cout<<endl<<endl;

    cout<<"Vector contains: ";
    for(int i=0;i<10;++i) cout<<vecInt.at(i)<<ends;///вывод на экран
    cout<<endl;
    return 0;
}

Пример работы программы:

CppStudio.com
Array contains: 1 1 1 1 1 1 1 1 1 1
Vector contains: 1 1 1 1 1 1 1 1 1 1

Как мы видим из данного примера, для заполнения массива одним числом требуется написать целый цикл, строки 9-12, а для заполнения вектора, нужна всего одна строка 14. Для вывода вектора на экран использовалась функция vector::at() которая в данном случае равносильна записи vecInt[i]; Используя вектора их можно инвертировать (производить реверс), как, показано в следующем примере.

#include <iostream>
#include <vector>
#include <iterator>
using namespace std;

int main()
{
   vector<int>::iterator it;///создаем итератор it
   vector<int>vecInt(10);///выделили место под 10 элементов
   cout<<"Vector contains: ";
   for(int i=0;i<10;++i) vecInt[i]=i;

   for(it=vecInt.begin();it<vecInt.end();++it)
   {
       cout<<*it<<ends;///вывод на экран вектора
   }
   cout<<endl;
   cout<<"\nVector capacity: "<<vecInt.capacity();
   cout<<endl<<endl;

   ///реверс вектора
   cout<<"Vector revers: ";
   for(auto rit=vecInt.rbegin();rit<vecInt.rend();++rit)
   {
       cout<<*rit<<ends;
   }
   cout<<endl;
   vecInt.clear();///очистили вектор

   cout<<"\nVector size: "<<vecInt.size();///размер вектора
   cout<<endl;
   return 0;
}

Пример работы программы:

CppStudio.com
Vector contains: 0 1 2 3 4 5 6 7 8 9
Vector capacity: 10
Vector revers: 9 8 7 6 5 4 3 2 1 0
Vector size: 0

В 8 строке создаем итератор it, строки 9-11 Вам должны быть понятны. В строках 13-16 используя итератор it, осуществляем вывод нашего вектора на экран. В строке 18  используется функция vector::capacity() которая возвращает количество элементов, которое может содержать вектор до того, как ему потребуется выделить больше места.  В строке 23-26 используя функции vector::rbegin() и vector::rend() мы осуществляем инвертирование вектора или иными словами реверс. Обратите внимание на использование auto (оно введено в стандарт с++11, если Ваш компилятор не поддерживает этот стандарт, будет выдано сообщение об ошибке), о нем будет рассказано более подробно в дальнейшем. В  строке 28 осуществляется полная очистка вектора с помощью функции vector::clear()

Автор: Marienko L.
Дата: 23.01.2014
Поделиться:

Комментарии

  1. Tordek

    В чем различие между методами size() и capacity()?

  2. Eho

    Еще было бы неплохо, сказать об интераторах.

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.