Как использовать Maps в C++

C++ Программирование и разработка

Maps C++ — это структура данных списка с парами ключ / значение. Структура данных имеет функции-члены. В C ++ есть карта и unordered_map. Карта на самом деле является упорядоченной картой. Порядок карты может быть восходящим или нисходящим по клавишам. По умолчанию используется порядок ключей по возрастанию. Возможностей для упорядоченной карты и неупорядоченной карты настолько много, что в этой статье будут рассмотрены только функции для карты (т.е. Упорядоченной карты).

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

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

    blackberry => dark blueblack
mango => yellow
passion fruit => purple
plum => purple
banana => yellow

Строки слева от списка образуют ключи; те, что справа, формируют значения. Пары ключ / значение не обязательно должны состоять из строки / строки. Это может быть int / string, string / float, int / float и т. Д. В карте C ++ пара ключ / значение является элементом, и такие элементы образуют список структуры данных. Структура данных карты обеспечивает быстрый поиск данных на основе ключей. Ключи уникальны, а структура карты однозначна. Это означает, что значения могут иметь дубликаты, а ключи — нет.

Чтобы использовать библиотеку карт в программе на C ++, программа должна начинаться с чего-то вроде:

    #include
#include <map>
using namespace std;

Если строки являются частью карты, рекомендуется использовать #include вместо . В этой статье объясняется, как использовать карту C ++.

Construction/Destruction

Карта — это ассоциативный контейнер, который должен быть построен из класса карты.

map(initializer_list<value_type>const Compare& = Compare()const Allocator& = Allocator())

Следующий оператор создает карту для приведенного выше списка путем инициализации:

map<string, string> mp{{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}{«plum»«purple»}{«banana»«yellow»}};

Обратите внимание на разграничение каждой пары.

= il

Следующая конструкция инициализации использует оператор присваивания:

map<string, string> mp = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}{«plum»«purple»}{«banana»«yellow»}};

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

Разрушение
Чтобы уничтожить карту, просто отпустите ее из поля зрения.

Сборка и подгонка Pairs

Для приведенной выше карты пара состоит из строкового ключа и строкового значения. Парный элемент может быть построен независимо от карты. Следующий сегмент кода создает пустой объект пары из класса Pair, а затем назначает один ключ и одно значение:

    pair pr;
pr.first = «blackberry»;
pr.second = «dark blue-black»;

Имя ключевого свойства — первое, а имя свойства значения — второе. Следующий код создает пустую карту и вставляет две пары с помощью функции-члена вставки карты.

    map mp;

pair pr0;
pr0.first = «blackberry»;
pr0.second = «dark blue-black»;

pair pr1;
pr1.first = «mango»;
pr1.second = «yellow»;

mp.insert(pr0);
mp.insert(pr1);

Отображение (печать) содержимого карты

В следующем коде используется итератор (it), созданный на основе первого элемента карты, для отображения пар ключ / значение на консоли:

    map mp = {{«plum»«purple»}{«mango»«yellow»}{«blackberry»«dark blue-black»}{«passion fruit»«purple»},  {«banana»«yellow»}};

for (map::iterator it = mp.begin(); it!=mp.end(); ++it) {
cout <first < » <second < yellow
blackberry => dark blue-black
mango => yellow
passion fruit => purple
plum => purple

=> здесь не имеет значения C ++. Он просто используется для отделения ключа от соответствующего значения на дисплее. Чтобы получить значение свойства указателя (итератора), используйте -> между указателем (итератором) и именем свойства. Итак, -> имеет значение в C ++.

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

Доступ к парам ключ / значение по-прежнему можно получить, используя схему for-element-in-list. Следующий фрагмент кода иллюстрирует это:

    map mp = {{«plum»«purple»}{«mango»«yellow»}{«blackberry»«dark blue-black»}{«passion fruit»«purple»},  {«banana»«yellow»}};

for (pair elem : mp)
cout << elem.first < » << elem.second < yellow
blackberry => dark blue-black
mango => yellow
passion fruit => purple
plum => purple

Как раньше. Обратите внимание, что здесь elem — это имя объекта, а не указатель (и не итератор). Таким образом, за ним следует точка, а не ->, чтобы получить доступ к свойству.

Доступ к элементу

T& operator[](key_type&& x)

Элемент, которого раньше не было на карте, можно включить с помощью его ключа с помощью оператора []. Значение элемента, который уже есть на карте, можно прочитать с помощью оператора [], используя его ключ. Следующая программа иллюстрирует это:

#include
#include <map>
#include
using namespace std;

int main()
{
map mp;
mp[«plum»] = «purple»;
mp[«passion fruit»] = «purple»;
mp[«blackberry»] = «dark blue-black»;

cout<<mp[«plum»]<<endl;
cout<<mp[«passion fruit»]<<endl;
cout<<mp[«blackberry»]<<endl;

return 0;
}

Результат:

    purple
purple
dark blueblack

const T& at(const key_type& x) const

Если карта объявлена ​​постоянной, то значения ключей изменить нельзя. Однако эту функцию-член можно использовать для чтения значений ключей. Следующий код иллюстрирует это:

    const map mp{{«plum»«purple»}{«mango»«yellow»}{«blackberry»«dark blue-black»}};

cout<<mp.at(«plum»)<<endl;
cout<<mp.at(«mango»)<<endl;
cout<<mp.at(«blackberry»)<<endl;

Результат:

    purple
yellow
dark blueblack

Емкость

size_type size() const noexcept

Длину карты можно определить с помощью функции-члена size (), как показано в следующем коде:

    const map mp{{«plum»«purple»}{«mango»«yellow»}{«blackberry»«dark blue-black»}};

cout<<mp.size()<<endl;

Выход 3.

[[nodiscard]] bool empty() const noexcept

Эта функция-член возвращает истину, если карта пуста, и ложь в противном случае. Пример:

    const map mp;
cout<<mp.empty()<<endl;

Выход 1 для истины. Было бы 0 для false (в противном случае).

Итераторы

iterator begin() noexcept

Это возвращает двунаправленный итератор, указывающий на первый элемент карты. Значение элемента (пары), на который он указывает, можно изменить. Пример кода:

    map mp{{«plum»«purple»}{«mango»«yellow»}{«blackberry»«dark blue-black»}};

map::iterator it;
for (it = mp.begin(); it!=mp.end(); it++) {
cout <first < » <second << endl;
}
cout<second = «
white«;

for (map::iterator it = mp.begin(); it!=mp.end(); it++) {
cout <first < » <second < dark blueblack
mango => yellow
plum => purple

blackberry => dark blueblack
mango => white
plum => purple

Значение второй пары ключ / значение было изменено. Обратите внимание на использование итератора end ().

reverse_iterator rbegin noexcept

Это возвращает двунаправленный обратный итератор, указывающий на последний элемент карты. Значение элемента, на который он указывает, можно изменить. Следующий код дает тот же результат, что и приведенный выше:

    map mp{{«plum»«purple»}{«mango»«yellow»}{«blackberry»«dark blue-black»}};

map::reverse_iterator it;
for (it = mp.rbegin(); it!=mp.rend(); it++) {
cout <first < » <second << endl;
}
cout<second = «
white«;

for (map::reverse_iterator it = mp.rbegin(); it!=mp.rend(); it++) {
cout <first < » <second < purple
mango => yellow
blackberry => dark blueblack

plum => purple
mango => white
blackberry => dark blueblack

То же значение для второй пары ключ / значение было изменено.

Модификаторы

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

Изменение карты связано с вставкой, размещением, извлечением, стиранием и очисткой. Установка и установка аналогичны, но установка лучше.

Emplace

pair<iterator,bool> a_uniq.emplace(args)

Эта функция-член вставляет литералы пары ключ / значение, разделенные запятой, без фигурных скобок, как показано в следующем коде:

    map mp = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}};

pair<map::iteratorbool> pr = mp.emplace(«banana»«yellow»);

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout<<endl;

cout <first < » << pr.second < yellow
blackberry => dark blueblack
mango => yellow
passion fruit => purple

banana => 1

Функция-член emplace (args) возвращает пару, соответствующую вставленному элементу. Ключ этой возвращаемой пары — итератор, указывающий на вставленный элемент. Значение этой возвращаемой пары — истина (1), если вставка произошла, и ложь (0), если вставка не произошла.

Обратите внимание на способ кодирования возвращаемого типа для emplace (args). Кроме того, возвращаемая пара не использовалась для получения ключа / значения вставленной пары карты в последнем операторе вывода. Здесь есть два типа пар: пара для карты и пара возврата. Они несовместимы. Если ключ уже существует на карте, возвращенный итератор будет указывать на существующий ключ; тогда логическое значение будет ложным.

Inserting

pair<iterator, bool> insert(value_type&& x)

Эта функция-член вставляет литералы пары ключ / значение, разделенные запятой, с фигурными скобками, как показано в следующем коде:

    map mp = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}};

pair<map::iteratorbool> pr = mp.insert({«banana»«yellow»});

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout<<endl;

cout <first < » << pr.second < yellow
blackberry => dark blueblack
mango => yellow
passion fruit => purple

banana => 1

Объяснение аналогично приведенному выше случаю.

pair<iterator, bool> insert(const value_type& x)

Можно вставить целый список. Сразу после прошивки происходит перестановка (по возрастанию). Иллюстрация:

    map mp = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}};

pair pr;
pr.first = «banana»;
pr.second = «yellow»;

pair<map::iteratorbool> ib = mp.insert(pr);

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout<<endl;

cout <first < » << ib.second < yellow
blackberry => dark blueblack
mango => yellow
passion fruit => purple

banana => 1

Объяснение аналогично приведенному выше случаю.

void insert(initializer_list<value_type>)

Можно вставить целый список. Сразу после прошивки происходит перестановка (по возрастанию). Иллюстрация:

    map mp = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}};

mp.insert({{«watermelon»«green»}{«grape»«pink»}{«apricot»,«orange»}});

for (auto elem : mp)
cout << elem.first < » << elem.second < orange
blackberry => dark blue-black
grape => pink
mango => yellow
passion fruit => purple
watermelon => green

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

void insert(InputIterator first, InputIterator last)

Можно вставить диапазон [i, j) из другой карты. Здесь i и j — итераторы. Иллюстрация:

    map mp1 = {{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}{«peach»«dark yellow»}{«papaya»«orange»}};
map::iterator itB = mp1.begin();
itB++;

map::iterator itE = mp1.end();
itE; itE;

map mp2 = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}};

mp2.insert(itB, itE);

for (auto elem : mp2)
cout << elem.first < » << elem.second < dark blue-black
grape => pink
mango => yellow
papaya => orange
passion fruit => purple

Обратите внимание, что элемент, соответствующий j первой карты, не был вставлен. Это соответствует обозначениям [i, j).

Erasing

size_type erase(const key_type& x)

Стирает элемент, идентифицированный ключом, и возвращает количество удаленных элементов (должно быть 1 в случае не-multimap). Иллюстрация:

    map mp = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}};

int n = mp.erase(«mango»);

cout<<n<<endl<<endl;

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout <<endl;

cout<<mp.size()< dark blue-black
passion fruit => purple

2

Удаленный элемент удаляется, насколько это возможно для пользователя. Так количество элементов сокращается.

iterator erase(const_iterator position)

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

    map mp = {{«blackberry»«dark blue-black»}{«mango»«yellow»}{«passion fruit»«purple»}};
map::iterator it = mp.begin();
it++;

map::iterator iter = mp.erase(it);

cout <first < » <second <<endl<<endl;

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout <<endl;

cout<<mp.size()< purple

blackberry => dark blueblack
passion fruit => purple

2

стирание итератора (сначала const_iterator, затем const_iterator)

При этом используются итераторы для удаления диапазона из упорядоченной карты. Он возвращает итератор, указывающий на элемент после стертого диапазона. Иллюстрация:

    map mp = {{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}{«peach»«dark yellow»}{«papaya»«orange»}};
for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout <<endl;

map::iterator itB = mp.begin();
itB++;

map::iterator itE = mp.end();
itE—; itE—;

map::iterator iter = mp.erase(itB, itE);

cout <first < » <second <<endl<<endl;

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout <<endl;

cout<<mp.size()< orange
grape => pink
papaya => orange
peach => dark yellow
strawberry => red

peach => dark yellow

apricot => orange
peach => dark yellow
strawberry => red

3

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

Clear

void clear() noexcept

Стирает все элементы карты, делая размер карты нулевым. Пример:

    map mp = {{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}};

mp.clear();

cout<<mp.size()<<endl;

На выходе 0.

Extraction
Это касается node_type — см. Позже.

Merging
При объединении двух карт элементы смешиваются по порядку (по возрастанию); пара ключ / значение не разделяется.

void a.merge(a2)

Элемент в a2 с таким же ключом в a не извлекается. Это касается node_type — см. Позже.

По возрастанию или по убыванию

По умолчанию карта становится восходящей по клавишам сразу после создания. Его можно сделать по убыванию. В угловых скобках шаблона третий параметр имеет тип по умолчанию, без . Так что набирать его не нужно. Чтобы карта отображалась по убыванию по ключу, необходимо использовать более крупный , как в следующем коде:

    map<string, string, greater> mp = {{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}};

for (auto elem : mp)
cout << elem.first < » << elem.second < red
grape => pink
apricot => orange

После создания карта упорядочивается по возрастанию или убыванию (по умолчанию по возрастанию). <строка> меньше или больше <строка> называется объектом сравнения.

Операции

поиск итератора (const key_type & x)

Возвращает итератор элемента, ключ которого является аргументом функции find (). Иллюстрация:

    map<string, string, greater> mp = {{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}};

map::iterator it = mp.find(«grape»);

cout <first < » <second < pink

iterator lower_bound(const key_type& x)

По умолчанию на карте элементы расположены по клавишам в возрастающем порядке. Если программист хочет знать итератор, который указывает на элемент, который не ниже, чем у определенного ключа, он должен использовать эту функцию-член. Иллюстрация:

    map mp = {{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}{«peach»«dark yellow»}{«papaya»«orange»}};

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout <<endl;

map::iterator it = mp.lower_bound(«papaya«);
cout <first < «
 <second < orange
grape => pink
papaya => orange
peach => dark yellow
strawberry => red

papaya => orange

В этой ситуации итератор указывает на ключевой элемент. Если ключ не найден, функция вернет итератор, указывающий сразу после конца карты. В этой ситуации он циклический и будет первым элементом карты.

iterator upper_bound(const key_type& x)

Если программист хочет знать итератор, который указывает на элемент с ключом больше k, он должен использовать эту функцию-член. Иллюстрация:

    map mp = {{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}{«peach»«dark yellow»}{«papaya»«orange»}};

for (auto elem : mp)
cout << elem.first < » << elem.second << endl;
cout <<endl;

map::iterator it = mp.upper_bound(«papaya«);
cout <first < «
 <second < orange
grape => pink
papaya => orange
peach => dark yellow
strawberry => red

peach => dark yellow

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

Специализированные алгоритмы

Ниже приводится синтаксис специальной функции алгоритма:

    template
void swap(map& x, map& y) noexcept(noexcept(x.swap(y)));

Вместо этого можно использовать следующий синтаксис:

void swap(map&)

Это меняет местами пары двух карт, которые не обязательно должны быть одинакового размера. Пример:

    map mp1 = {{«plum»«purple»}{«mango»«yellow»}{«blackberry»«dark blue-black»}{«passion fruit»«purple»},  {«banana»«yellow»}};

map mp2 = {{«watermelon»«green»}{«grape»«pink»}{«apricot»«orange»}{«strawberry»«red»}{«peach»«dark yellow»}{«papaya»«orange»}};

mp1.swap(mp2);

cout << «New mp1:» << endl;
for (auto elem : mp1)
cout << elem.first < » << elem.second << endl;
cout<<endl;

cout << «New mp2:» << endl;
for (auto elem : mp2)
cout << elem.first < «
 << elem.second << endl;

Заключение

Карта состоит из пар ключ / значение. Он упорядочен по клавишам, по возрастанию или по убыванию. Порядок по умолчанию — по возрастанию. Основные функции-члены для карты: map (), operator [], at (), size (), empty (), begin (), end (), rbegin (), rend (), emplace (), insert (), erase (), clear (), find (), lower_bound (), upper_bound () и a1swap (a2).

 

 

Оцените статью
bestprogrammer.ru
Добавить комментарий