Контейнер map: функции insert(), emplace(), lower_bound(), upper_bound()

Поскольку, Вы уже сталкивались с функцией map::insert(), в следующем примере, я покажу, альтернативные варианты добавления элементов в  контейнер multimap и map, например:

#include <iostream>
#include <map>

using namespace std;
int main ()
{
  multimap<float,string> myMultimapExample;
  map<string,float> myMapExample;

  /// первый вариант
  myMapExample.insert ( pair<string,float>("Desk",0.01) );
  myMapExample.insert ( pair<string,float>("Table",0.02) );
  myMultimapExample.insert ( pair<float,string>(0.01,"Desk") );
  myMultimapExample.insert ( pair<float,string>(0.01,"Table") );

  /// второй вариант
  multimap<float,string>::iterator itMultimapExample = myMultimapExample.begin();///итератор указывает на начало multimap
  map<string,float>::iterator itMapExample = myMapExample.begin();
  myMapExample.insert ( itMapExample, pair<string,float>("Pencil",0.03) );
  myMultimapExample.insert ( itMultimapExample, pair<float,string>(0.03,"Pencil") );

  /// третий вариант
  map<string,float> myMapExampleDifferent;
  multimap<float,string> myMultimapExampleDifferent;
  myMapExampleDifferent.insert( myMapExample.begin(),myMapExample.find("Table") );
  myMultimapExampleDifferent.insert( myMultimapExample.begin(),myMultimapExample.find(0.03) );

  /// вывод на экран map и multimap:
  cout << "myMapExample: \t\t myMultimapExample:\n";
  for ( itMapExample = myMapExample.begin(),itMultimapExample = myMultimapExample.begin(); itMapExample != myMapExample.end(); ++itMapExample,++itMultimapExample)
  {
      cout << itMapExample->first << " : " << itMapExample->second << "\t\t   " << itMultimapExample->first << " : " << itMultimapExample->second << endl;
  }

  auto itMapExampleDif = myMapExampleDifferent.begin();
  auto itMultimapExampleDif = myMultimapExampleDifferent.begin();
  cout << "\nmyMapExampleDifferent: \t myMultimapExampleDifferent:\n";
  for ( itMapExampleDif,itMultimapExampleDif; itMapExampleDif != myMapExampleDifferent.end(); ++itMapExampleDif,++itMultimapExampleDif)
  {
      cout << itMapExampleDif->first << " : " << itMapExampleDif->second << "\t\t    " << itMultimapExampleDif->first << " : " << itMultimapExampleDif->second << '\n';
  }

  return 0;
}

Работа программы:

CppStudio.com
myMapExample:            myMultimapExample:
Desk : 0.01                0.01 : Desk
Pencil : 0.03              0.01 : Table
Table : 0.02               0.03 : Pencil
myMapExampleDifferent:   myMultimapExampleDifferent:
Desk : 0.01                 0.01 : Desk
Pencil : 0.03               0.01 : Table

Если Вы используете MVS 2013 или MVS 2012, то не исключено возникновение вот такой ошибки:

Error C2679: бинарный «<<«: не найден оператор, принимающий правый операнд типа «const std::string» (или приемлемое преобразование отсутствует)

В программе показано три варианта заполнения контейнера multimap и map.

  • Вариант №1 — или самый распространенный вариант. В строке 11 и 12 с помощью функции map:: insert(), мы добавляем элементы в map. Функция принимает два аргумента, первый аргумент ключ, у нас это тип string, второй это значение, у нас это тип floatСтроки 13 и 14 идентичны строками 11 и 12, но там элементы добавляются в multimap.
  • Вариант №2 — с использованием итератора. В строке 17 создаем итераторitMultimapExample, в строке 18, итератор itMapExample. Функцииmap::insert(), в строке 19 мы  передаем два аргумента (первым аргументом выступает наш итератор itMapExample, а вторым, пара  ключзначение). Строка 20 равносильна строке 19,  только там функция map::insert(), применяется к контейнеру multimap. Может возникнуть вопрос, чем первый вариант отличается от второго? Ответ, тем, что нашим итератором мы рекомендуем позицию, с которой следует начинать поиск позиции элемента, который мы хотим вставить.
  • Вариант №3 — с использованием функции map::find(). В строке 23, 24 объявляем еще один  контейнер map и multimap. Строку 25 можно прочитать так: заполняй контейнер myMapExampleDifferent,  начиная с начала myMapExample, пока в контейнере myMapExample не встретишь ключ Table. Этот ключ не  будет вставлен в myMapExample. Строка 26 выполняет предыдущее действие, но применительно к  multimap контейнеру. Вывод на экран myMapExample и myMultimapExample осуществляется в строках 30-33, а вывод myMapExampleDifferent и myMultimapExampleDifferent строках 38-41 .

Multimap кроме функции map::insert(), поддерживает еще функцию map::emplace(), рассмотрим  пример:

#include <iostream>
#include <map>

using namespace std;
int main ()
{
  multimap<char,float> mymultimap;
  map<char,float> mymap;

  ///заполняем multimap
  mymultimap.insert( pair<char,float>('a',0.1) );
  mymultimap.insert( pair<char,float>('b',0.2) );
  mymultimap.insert( pair<char,float>('d',0.4) );
  mymultimap.insert( pair<char,float>('e',0.5) );

  ///заполняем map
  mymap.insert( pair<char,float>('f',5.3) );
  mymap.insert( pair<char,float>('g',4.32) );
  mymap.insert( pair<char,float>('i',23.41) );
  mymap.insert( pair<char,float>('r',6.5) );

  ///вставляем элементы в multimap
  mymultimap.emplace('c',0.3);
  mymultimap.emplace('b',9.9);
  cout << "mymultimap have:" << endl;
  for (auto it = mymultimap.begin(); it != mymultimap.end(); ++it)
  {
      cout << it->first << " : " << it->second << endl;
  }

  auto lowerMap=mymap.lower_bound('g');/// нижняя граница map
  auto upperMap=mymap.upper_bound('i');///верхняя граница map
  auto lowerMultimap=mymultimap.lower_bound('b');/// нижняя граница multimap
  auto upperMultimap=mymultimap.upper_bound('d');///верхняя граница multimap

  mymultimap.erase(lowerMultimap,upperMultimap);
  mymap.erase(lowerMap,upperMap);
  auto itMultimap = mymultimap.begin();
  auto itMap = mymap.begin();
  cout << "\nmymultimap have: \t mymap have:" << endl;
  for (itMultimap,itMap; itMultimap != mymultimap.end(); ++itMultimap,++itMap)
  {
      cout << itMultimap->first << " : " << itMultimap->second << "\t\t  " << itMap->first  << " : " << itMap->second << endl;
  }
  return 0;
}

Работа программы:

CppStudio.com
mymultimap have:
a : 0.1
b : 0.2
b : 9.9
c : 0.3
d : 0.4
e : 0.5
mymultimap have:         mymap have:
a : 0.1                  f : 5.3
e : 0.5                  r : 6.5

В строках 11-14 происходит заполнение контейнера multimap, в строках 17-20 происходит заполнение контейнера map. В строке 23 встречается функция  map::emplace(), которая равносильна функции map::insert, но ей не нужно, явно, каждый раз,  указывать тип переменной. В строках 26-29 осуществляет вывод на экран контейнера multimap.  Контейнер map не поддерживает функцию map::emplace(). В строке 31 мы встречаем функцию map::lower_bound(). Эта функция принимает только один аргумент и возвращает первую позицию в которую может быть вставлен этот элемент. С помощью функции  map::lower_bound(), создаем итератор, указывающий на ключ g в контейнере map. В 32 строке мы встречаем функцию map::upper_bound(), она возвращает последнюю позицию , в которую может быть вставлен элемент. В строке 32 создаем еще один итератор, но уже с помощью функции map::upper_bound() и указывающий на ключ i. В строках 33, 34, выполняется тоже, но с контейнером multimap. Данные итераторы  выступают в роли «границ», где  при помощи map::erase() в строке 38, 39, мы очищаем оба  контейнера (границы контейнеров, тоже стираются). Что осталось в контейнерах, показано в  строках 43-46, где осуществляется вывод на экран.

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

Комментарии

  1. mpavelFax

    Официальная работа в интернете

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

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