Структура 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, описание которой приводится ниже.