вектор в c

Векторы в C++: для начинающих

Всем привет! До этого дня мы использовали чистые массивы. Чистые — это значит простые массивы, не имеющие у себя в багаже различных функций. В этом уроке мы пройдем нечистые массивы — векторы.

Быстрый переход по статье:

Как это работает Что такое вектор (vector)

Вектор — это структура данных, которая уже является моделью динамического массива.

Давайте вспомним о том, что для создания динамического массива (вручную) нам нужно пользоваться конструктором new и вдобавок указателями. Но в случае с векторами всего этого делать не нужно.
Вообще, по стандарту пользоваться динамическим массивом через конструктор new — не есть правильно. Так как в компьютере могут происходить различные утечки памяти.

Как это сделать Как создать вектор (vector) в C++

Сначала для создания вектора нам понадобится подключить библиотеку — <vector>, в ней хранится шаблон вектора.

Кстати, сейчас и в будущем мы будем использовать именно шаблон вектора. Например, очередь или стек, не созданные с помощью массива или вектора, тоже являются шаблонными.

Далее, чтобы объявить вектор, нужно пользоваться конструкцией ниже:

  • Вначале пишем слово vector.
  • Далее в угольных скобках указываем тип, которым будем заполнять ячейки.
  • И в самом конце указываем имя вектора.

Вот пример:

В примере выше мы создали вектор строк.

Кстати, заполнить вектор можно еще при инициализации (другие способы мы пройдем позже — в методах вектора). Делается это также просто, как и в массивах. Вот так:

После имени вектора ставим знак равенства и скобки, в которых через пробел указываем значение элементов.

Такой способ инициализации можно использовать только в C++!

Так, чтобы заполнить вектор строками, нам нужно использовать кавычки — "строка".

Второй способ обратиться к ячейке

Мы знаем, что в векторе для обращения к ячейке используются индексы. Обычно мы их используем совместно с квадратными скобками [].

Но в C++ есть еще один способ это сделать благодаря функции — at(). В скобках мы должны указать индекс той ячейки, к которой нужно обратиться.

Вот как она работает на практике:

Давайте запустим эту программу:

fuctsiya_at.cpp
5
Process returned 0 (0x0) execution time : 0.010 s
Press any key to continue.

Как указать количество ячеек для вектора

Указывать размер вектора можно по-разному. Можно это сделать еще при его инициализации, а можно хоть в самом конце программы. Вот, например, способ указать длину вектора на старте:

Так в круглых скобках () после имени вектора указываем первоначальную длину. А вот второй способ:

Первая строчка нам уже знакома. А вот во второй присутствует незнакомое слово — reserve, это функция, с помощью которой мы говорим компилятору, какое количество ячеек нам нужно использовать.

Вы можете задать логичный вопрос:»А в чем разница?». Давайте создадим два вектора и по-разному укажем их количество ячеек.

Запускаем программу:

reserve.cpp
Значения первого вектора (с помощью скобок): 0 0 0
Значения второго вектора (с помощью reserve): 17 0 0
Process returned 0 (0x0) execution time : 0.010 s
Press any key to continue.

Как видим, в первом случае мы вывели три нуля, а во втором: 17, 0, 0.

Все потому, что при использовании первого способа все ячейки автоматически заполнились нулями.

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

Поэтому, когда мы вывели второй вектор, в нем уже находились какие-то рандомные числа — 17, 0, 0. Обычно они намного больше. Можете кстати попробовать создать переменную и вывести ее значение.

Нужно помнить! При использовании второго способа есть некоторый плюс — по времени. Так как для первого способа компилятор тратит время, чтобы заполнить все ячейки нулями.

 Как сравнить два вектора

Если в середине программы нам понадобиться сравнить два массива, мы, конечно, используем цикл for и поочередно проверим все элементы.

Вектор снова на шаг впереди! Чтобы нам сравнить два вектора, потребуется применить всего лишь оператор ветвления if.

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

Вот так бы выглядела программа выше, если бы мы не использовали знак равенства для векторов.

  1. Сначала мы создали  булеву переменную flag равную true. У нее задача такая:
    • Если в условии (строки  5 — 10) она станет равна false — то значит эти векторы не равны и условие (строки 14 — 16) не будет выполняться.
    • Если же она после цикла (строки 3 — 12) останется равна true — то в условии (строки 14 — 16) мы сообщим пользователю, что они равны.
  2. В условии (строка 3) проверяем размеры двух векторов на равенство.
  3. И если условие (строки 5 — 10) будет равно true — то мы сообщим пользователю, что эти два вектора не равны.

Как это сделать Как создать вектор векторов

Понятно, что вам может понадобиться записать числа в двумерный массив. Но зачем использовать массив, если можно оперировать векторами.

Сейчас вы узнаете, как создать вектор векторов или простым языком массив векторов.

Как можно увидеть, нам пришлось только добавить слова vector и еще его <тип>.

А чтобы указать количества векторов в векторе нам потребуется — метод resize().

Но есть еще одни способ добавления векторов в вектор. Для этого способа мы будем использовать функцию push_back() (читайте ниже, что она делает).

  • В аргументах функции push_back() находится — имя контейнера который мы хотим добавить. В нашем случае — vector.
  • А дальше идет тип контейнера — <тип>.
  • И все заканчивается отрывающей и закрывающей скобкой ().

Для двумерного вектора тоже можно указать значения еще при инициализации:

{1, 4, 7} — это значения элементов первого массива (первого слоя). Такие блоки значений {1, 4, 7} должны разделяться запятыми.

 Методы для векторов:

Сейчас мы разберем некоторые методы, которые часто используются вместе с векторами. Метод — это функция, которая относится к определенному STL контейнеру.

В нашем случае этим STL контейнером является вектор. Если вы дальше собираетесь оперировать векторами — лучше все перечисленные функции запомнить.

1) size() и empty()

Если нам требуется узнать длину вектора, понадобится функция — size(). Эта функция практически всегда используется вместе с циклом for.

Также, если нам требуется узнать пуст ли стек, мы можем использовать функцию — empty().

  • При отсутствии в ячейках какого-либо значения это функция возвратит — true.
  • В противном случае результатом будет — false.

Вот пример с ее использованием:

2) push_back() и pop_back()

Как мы сказали выше, у векторов имеются методы, которые помогают оптимизировать и улучшить жизнь программистов. Одни из самых используемых функций это — push_back() и pop_back().

  • С помощью функции push_back() мы можем добавить ячейку в конец вектора.
  • А функция pop_back() все делает наоборот — удаляет одну ячейку в конце вектора.

Использование функции push_back() без указания значения ячейки — невозможно. Так или иначе, придется это значение указать!

Давайте разберемся, как работают эти функции на практике:

Вот что будет при запуске:

push_back_and_pop_back.cpp
апельсин груша яблоко вишня
апельсин груша яблоко
Process returned 0 (0x0) execution time : 0.010 s
Press any key to continue.

Кстати, можно сделать вот так:

Мы сохранили значение удаляемой ячейки в переменную — val.

Давайте запустим эту программу:

push_back.cpp
груша
Process returned 0 (0x0) execution time : 0.010 s
Press any key to continue.

3) insert()

Выше мы вам показали функцию push_back(), но то же самое можно сделать, используя функцию — insert(). Только с помощью нее еще можно добавлять элементы в начало вектора.

Эта функция имеет такую конструкцию:

<итератор> — про него мы поговорим в другом уроке. Это тема которая требует подробного изучения. Сейчас вам нужно знать только о том, что функция:

  • begin() — указывает на начала вектора.
  •  end() — указывает на конец вектора.

<значение> — сюда мы должны вписать значение добавляемой ячейки.

Если вы в <итератор> указали именно итератор, а не функции begin() и end(), то элемент будет добавлен именно после той ячейки, на которую указывает итератор.

Давайте посмотрим, как insert() работает на примере:

При запуске программы, мы увидим это:

insert.cpp
2 3
1 2 3
1 2 3 4
Process returned 0 (0x0) execution time : 0.010 s
Press any key to continue.

На иллюстрациях ниже показано, как vec_string изменялся в программе:
insert_v_c

insert_v_c

insert_v_c

insert_v_c

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

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

4) front() и back()

Для того, чтобы мы могли просматривать первую и последнюю ячейки у нас имеются функции: front() и back().

Завершение урока домашним заданием Упражнение

Чтобы как следует запомнить этот материал, создайте вектор и поочередно примените все выше сказанные функции.



Тест на тему «Векторы». Проверь себя!

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

If loading fails, click here to try again

Если ты полностью разобрался в данном материале, то попробуй пройти несложный тест, который сможет выявить твои слабые стороны.
Начать


На этом все! Надеемся, вы узнали для себя что-то новое! Если хотите задать вопрос, то пишите в комментарии. Удачи!




Комментарии к записи “Векторы в C++: для начинающих”

Добавить комментарий

Ваш адрес email не будет опубликован.

  • Наталья:

    Подскажите, пожалуйста, где можно скачать дистрибутив С++, поддерживающий векторы?

    • Дмитрий:

      Здравствуйте. Любой компилятор C++ должен поддерживать STL (Standard Template Library), а STL в свою очередь содержит реализации векторов (vector).

  • Наталья:

    Спасибо за ответ, Дмитрий! Раз у нас тема «Для начинающих», задам такой вопрос: я подключила библиотеку
    #include
    а компилятор заругался. Что я не так сделала? Раньше никогда с векторами не работала, может, какая-то тонкость есть, которой я не знаю? С++ у меня DOS-ский.

  • Наталья:

    ХМ… Имя библиотеки vector.h почему-то не пропечаталось…

  • German:

    Как мне с помощью вектора из массива с разными элементами вывести все не равные между собой элементы, т.е. например есть массив a[7]={1,1,2,3,4,3,7}, а вывести должен a[3]={2,4,7}.

    • Дмитрий:

      Не понимаю фразу «вектора из массива», уточните. Как я понял элементы находятся в одномерном массиве или векторе. Чтобы решить данную задач создадим массив int score[100000] = {0} (размер массива зависит от входных данных), далее пройдемся по всем элементам массива a увеличивая значение ячейки массива score[arr[i]]++. Если значение какой нибудь ячейки больше 1, значит есть повторяющие элементы данного значения и не надо выводить a[i].

      Также есть решение с использованием контейнера map.

  • Николай:

    В коде сравнения двух векторов через цикл (поэлементное сравнение), если размеры массивов разные, то переменная flag останется true, то есть вывод будет: «Они не равны!Они равны!» — вероятно, нужно для этого случая также присвоить flag значение false

    • Дмитрий:

      Спасибо, исправил!

      • Vlad:

        » int num = vec_string.pop_back(); // присвоили значение удаляемой ячейке»
        Не понимаю каким образом мы можем целочисленной переменной присвоить значение удаляемого элемента вектора строки. Оно и не работает собственно. Очепятка?

  • Игорь:

    Подскажите, пожалуйста, как вывести в консоли «Process returned 0 (0x0) execution time : 0.010 s»
    после каждого выполнения программы

    • Дмитрий:

      Можете использовать какую нибудь библиотеку для измерения скорости программы. Какую среду разработки вы используете? В codeblocks все должно выводиться.

  • Мария:

    Подскажите пожалуйста, как создать вектор неизвестной длины, который вводят с клавиатуры?

    • Дмитрий:

      Для этого вам нужно инициализировать вектор. Далее добавляете в векторе элементы с помощью функции push_back(): my_vec.push_back(elem)

  • Sergey:

    thread horse1([&]() {horses_actions(&horses_status); });