Перейти к содержимому

Как добавить элемент в вектор пару с

  • автор:

Структура pair

Иногда удобно в одной переменной хранить одновременно два значения, например, два целых числа. Например, координаты точки на плоскости удобно хранить в одной переменной, содержащих два числа: x-координату и y-координату. Для этого в STL есть шаблон pair (пара), особенно удобно использовать pair для сортировки объектов.

Pair является переменной, объединяющей в себе два значения, которые могут быть одного или разных типов. Например, чтобы создать переменную типа pair, содержащую два поля типа int нужно использовать следующее объявление:

pair a;

Теперь переменная a будет хранить в себе два значения типа int . Получить доступ к первому значению можно при помощи записи a.first , а ко второму значению — a.second , они называются полями переменной. Каждому полю можно присваивать независимые значения, например, так:

a.first = 1; a.second = 2;

Присвоить одновременно два значения обоим полям пары можно при помощи функции make_pair , принимающующей два аргумента и возвращающей значение типа pair с соответствующими полями:

a = make_pair(1, 2);

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

pair a, b; . b = a;

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

cin >> a; cout 

Вместо этого нужно отдельно считывать или выводить каждое поле пары.

Можно создавать пару с полями разных типов, например, чтобы поле first имело тип double , а поле second — string , нужно использовать запись pair .

С парой, как с целым (то есть одновременно с двумя полями структуры) можно выполнять следующие операции: = , == , != , < , , >= , а также использовать в качестве аргумента функции swap . При использовании операций сравнения (типа меньше, больше и т.д.) пары сравниваются в лексикографическом порядке, то есть сначала по полю first , а если поля first равны, то по полю second .

vector < pair< int, int>> a

Обратите внимание на пробел между закрывающими угловыми скобками: он обязателен, иначе компилятор будет считать это операцией “ >> ”

Как добавить элемент в вектор пару с

Для добавления элементов в вектор применяется функция push_back() , в которую передается добавляемый элемент:

#include #include int main() < std::vectornumbers; // пустой вектор numbers.push_back(5); numbers.push_back(3); numbers.push_back(10); for(int n : numbers) cout << n << "\t"; // 5 3 10 std::cout

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

Функция emplace_back() выполняет аналогичную задачу - добавляет элемент в конец контейнера:

std::vector numbers< 1, 2, 3, 4, 5 >; numbers.emplace_back(8); // numbers = < 1, 2, 3, 4, 5, 8 >;

Добавление элементов на определенную позицию

Ряд функций позволяет добавлять элементы на определенную позицию.

  • emplace(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos
  • insert(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos, аналогично функции emplace
  • insert(pos, n, value) : вставляет n элементов value начиная с позиции, на которую указывает итератор pos
  • insert(pos, begin, end) : вставляет начиная с позиции, на которую указывает итератор pos, элементы из другого контейнера из диапазона между итераторами begin и end
  • insert(pos, values) : вставляет список значений начиная с позиции, на которую указывает итератор pos
std::vector numbers< 1, 2, 3, 4, 5 >; auto iter = numbers.cbegin(); // константный итератор указывает на первый элемент numbers.emplace(iter + 2, 8); // добавляем после второго элемента numbers = < 1, 2, 8, 3, 4, 5>;
std::vector numbers1< 1, 2, 3, 4, 5 >; auto iter1 = numbers1.cbegin(); // константный итератор указывает на первый элемент numbers1.insert(iter1 + 2, 8); // добавляем после второго элемента //numbers1 = < 1, 2, 8, 3, 4, 5>; std::vector numbers2 < 1, 2, 3, 4, 5 >; auto iter2 = numbers2.cbegin(); // константный итератор указывает на первый элемент numbers2.insert(iter2 + 1, 3, 4); // добавляем после первого элемента три четверки //numbers2 = < 1, 4, 4, 4, 2, 3, 4, 5>; std::vector values < 10, 20, 30, 40, 50 >; std::vector numbers3 < 1, 2, 3, 4, 5 >; auto iter3 = numbers3.cbegin(); // константный итератор указывает на первый элемент // добавляем после первого элемента три первых элемента из вектора values numbers3.insert(iter3 + 1, values.begin(), values.begin() + 3); //numbers3 = < 1, 10, 20, 30, 2, 3, 4, 5>; std::vector numbers4 < 1, 2, 3, 4, 5 >; auto iter4 = numbers4.cend(); // константный итератор указывает на позицию за последним элементом // добавляем в конец вектора numbers4 элементы из списка < 21, 22, 23 >numbers4.insert(iter4, < 21, 22, 23 >); //numbers4 = < 1, 2, 3, 4, 5, 21, 22, 23>;

Удаление элементов

Если необходимо удалить все элементы вектора, то можно использовать функцию clear :

std::vector v < 1,2,3,4 >; v.clear();

Функция pop_back() удаляет последний элемент вектора:

std::vector v < 1,2,3,4 >; v.pop_back(); // v =

Если нужно удалить элемент из середины или начала контейнера, применяется функция std::erase() , которая имеет следующие формы:

  • erase(p) : удаляет элемент, на который указывает итератор p. Возвращает итератор на элемент, следующий после удаленного, или на конец контейнера, если удален последний элемент
  • erase(begin, end) : удаляет элементы из диапазона, на начало и конец которого указывают итераторы begin и end. Возвращает итератор на элемент, следующий после последнего удаленного, или на конец контейнера, если удален последний элемент

std::vector numbers1 < 1, 2, 3, 4, 5, 6 >; auto iter = numbers1.cbegin(); // указатель на первый элемент numbers1.erase(iter + 2); // удаляем третий элемент // numbers1 = < 1, 2, 4, 5, 6 >std::vector numbers2 = < 1, 2, 3, 4, 5, 6 >; auto begin = numbers2.cbegin(); // указатель на первый элемент auto end = numbers2.cend(); // указатель на последний элемент numbers2.erase(begin + 2, end - 1); // удаляем с третьего элемента до последнего // numbers2 =

Также начиная со стандарта С++20 в язык была добавлена функция std::erase() . Она не является частью типа vector. В качестве первого параметра она принимает вектор, а в качестве второго - элемент, который надо удалить:

std::vector numbers3 < 1, 2, 3, 1, 5, 6 >; std::erase(numbers3, 1); // numbers3 =

В данном случае удаляем из вектора numbers3 все вхождения числа 1.

Размер вектора

С помощью функции size() можно узнать размер вектора, а с помощью функции empty() проверить, путой ли вектор:

#include #include int main() < std::vectornumbers; if(numbers.empty()) std::cout

С помощью функции resize() можно изменить размер вектора. Эта функция имеет две формы:

  • resize(n) : оставляет в векторе n первых элементов. Если вектор содержит больше элементов, то его размер усекается до n элементов. Если размер вектора меньше n, то добавляются недостающие элементы и инициализируются значением по умолчанию
  • resize(n, value) : также оставляет в векторе n первых элементов. Если размер вектора меньше n, то добавляются недостающие элементы со значением value

std::vector numbers1 < 1, 2, 3, 4, 5, 6 >; numbers1.resize(4); // оставляем первые четыре элемента - numbers1 = numbers1.resize(6, 8); // numbers1 =

Важно учитывать, что применение функции resize может сделать некорректными все итераторы, указатели и ссылки на элементы.

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

Функция assign() позволяет заменить все элементы вектора определенным набором:

std::vector langs = < "Java", "JavaScript", "C">; langs.assign(4, "C++"); // langs =

В данном случае элементы вектора заменяются набором из четырех строк "C++".

Также можно передать непосредственно набор значений, который заменит значения вектора:

std::vector langs< "Java", "JavaScript", "C">; langs.assign(< "C++", "C#", "C">); // langs =

Еще одна функция - swap() обменивает значения двух контейнеров:

std::vector clangs < "C++", "C#", "Java" >; std::vector ilangs < "JavaScript", "Python", "PHP">; clangs.swap(ilangs); // clangs = < "JavaScript", "Python", "PHP">; for(std::string lang : clangs)

Сравнение векторов

Векторы можно сравнивать - они поддерживают все операции сравнения: , =, ==, !=. Сравнение контейнеров осуществляется на основании сравнения пар элементов на тех же позициях. Векторы равны, если они содержат одинаковые элементы на тех же позициях. Иначе они не равны:

std::vector v1 ; std::vector v2 ; std::vector v3 ; bool v1v2 = v1 == v2; // true bool v1v3 = v1 != v3; // true bool v2v3 = v2 == v3; // false

Вектор пары в C++

У меня появляется ошибка:request for member "push_back" in "g" which is of non-class type "std::vector > 2000". Скажите,пожалуйста,в чём моя ошибка?

Отслеживать
задан 28 июн 2016 в 14:44
Vladslav Rublevskii Vladslav Rublevskii
85 1 1 золотой знак 1 1 серебряный знак 8 8 бронзовых знаков

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

На самом деле вполне информативное сообщение: вы создали массив (на 2000 элементов) вектров.

Расписываю подробнее: vector<> - шаблон, но для простоты будем считать что это класс. Если мы создаём объект класса то нужно писать

Class class(/*params*/); 

Если в классе существует конструктор без параметров то () можно не указывать например так:

 Class class; 

Когда вы пишите

Class class[10]; 

То компилятор это понимает как создать массив на 10 объектов класса Class с констуктором по умолчанию (без параметров). Если конструктора без параметров нет - то произойдёт ошибка компиляции. Пример:

class C< public: C(int a)<>; //C()<>; >; int main()

У массива нет метода push_back что и приводит к ошибке компиляции. Я не знаю что именно вы хотите, поэтому либо пишите

g[0].push_back(make_pair(a,b)); 
vector > g; 

либо, если вам важен размер, то используйте что-то типо

vector > g; . g.resize(2000); //g.reserve(2000); 

pair

В программировании часто возникает необходимость обрабатывать два объекта, например, простую пару чисел, как один. Такая задача стала особенно актуальной, когда в синтаксис программирования были внедрены ассоциативные массивы с их парой: название поля –> значение поля. Причём типы обоих значений в паре могут быть совершенно разными – в этом и состоит особая ценность рассматриваемой структуры и на это необходимо обратить особое внимание.

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

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *