Как удалить элемент из map c
Перейти к содержимому

Как удалить элемент из map c

  • автор:

Как удалить элемент из map c

линукс, g++ ,
g++ (GCC) 3.3.5 (Debian 1:3.3.5-13)

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

ROUTESMAP::iterator i = banksRoutes.begin();
while(i != banksRoutes.end())
if(i->second.GetGatewayId() == droppedGateId)
i = banksRoutes.erase(i);

но так не канает. у микрософа б канало, а в линуксе видимо erase возвращает void и ребалансирует дерево после удаления элемента..

думал сделать bankRoutes.erase(i++),
но если после erase дерево ребалансируется, то все итераторы после становятся инвалидными наверное.

подскажите, как все таки удалить нужноые мне элементы?

Вставка и удаление элементов из std::map в цикле

Можно ли в цикле по std::map на каждом шаге совершать несколько удалений и вставок элементов в этот же контейнер? Т.е. будет ли правильно работать следующий код?

std::map my_map; for (auto&& it = my_map.begin(); it != my_map.end();) < if (pair.second == 42) it = my_map[pair.first].erase(it); if (2 + 2 == 4) it = my_map.emplace(42, 42).first; //. if (no_insert_and_no_erase) ++it; >

Отслеживать
8,582 4 4 золотых знака 29 29 серебряных знаков 53 53 бронзовых знака
задан 15 мая 2017 в 19:48
31 1 1 серебряный знак 2 2 бронзовых знака
Ну по идее должен, почему бы ему не работать? Если только скомпилируется.
15 мая 2017 в 19:50

@VladD я исхожу из той логики, что при удалении возвращенный итератор может проскочить вставленный на этой итерации элемент

15 мая 2017 в 19:53
Ну у вас же сначала удаление?
15 мая 2017 в 19:54
@VladD нет, имеется в виду, что порядок произвольный и количество тоже
15 мая 2017 в 19:55
Только вот непонятна логика со вставкой: если вставка будет в конец, вы перепрыгнете весь список?
15 мая 2017 в 19:55

1 ответ 1

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

pair < iterator, bool>container::emplace (args) //std::map

iterator container::emplace (args) // std::multimap

Для всех контейнеров(ассоциативных и неупорядоченных) операция вставки сохраняет корректность ссылок на существующие элементы. Для ассоциативных контейнеров все итераторы установленные на существующие элементы остаются корректными.

iterator container::erase(iterator) (С++11)

При удалении элемента главное не удалить итератор ссылающийся на этот элемент.

std::map coll; . for(auto pos = coll.begin(); pos != coll.end(); ++pos) < if(pos->second == value) coll.erase(pos); // Ошибка во время выполнения > 

В С++11 функция-член erase всегда возвращает значение следующего элемента.

std::map coll; . for(auto pos = coll.begin(); pos != coll.end();) < if(pos->second == value) < pos = coll.erase(pos); // C++11 >else < ++pos; >> 

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

template bool replaceKey(Cont& c, const typename Cont::key_type& oldKey, const typename Cont::key_type& newKey) < typename Cont::iterator pos; pos = c.find(oldKey); if(pos != c.end()) < //Вставка нового элемента c.insert( typename Cont::value_type(newKey, pos->second) ); //Удаляем старый элемент c.erase(pos); return true; > else < return false; >> 

Для мапы также существует более простой способ:

coll["newKey"] = coll["oldKey"]; coll.erase("oldKey"); 

Удалить элементы из контейнера map

Author24 — интернет-сервис помощи студентам

1) Здесь что-то непонятное первый раз сталкиваюсь при выводе map1.size() показывает 1, но цикл крутит 4 раза.
2) Почему при удалении показывает 0, а сами элементы не удаляются. Как их удалить?

Здесь вы можете заказать любую студенческую или школьную работу.

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Не получается вывести и удалить последний элемент контейнера map
Не получается вывести и удалить последний элемент контейнера map. Для первого (begin) всё.

Использование контейнера map
Доброе утро) Никак не пойму как пользоваться контейнером map и зачем он, вообще, нужен?! Скажем.

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

Копирование содержимого контейнера map
Итак, есть контейнер map<string,fsElem *>, где fsElem — базовый класс, также есть наследуемый от.

2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826

ЦитатаСообщение от ElvenDragon Посмотреть сообщение

map1.size() показывает 1, но цикл крутит 4 раза

Потому что цикл такой через попу

ЦитатаСообщение от ElvenDragon Посмотреть сообщение

Почему при удалении показывает 0

Если, что-то показывает — то значит вы не удалили

ЦитатаСообщение от ElvenDragon Посмотреть сообщение

Как их удалить?
С этого надо было начинать, а не заканчивать)

map1.erase( map1.find( rand() % 4 ) );

А про то, что цикл крутит много, так вы операцией map1[z] сами запихуете туда значения — почитайте про map1[z] и map1.at(z) — в чём у них разница

Да и вывод просто на экран — легче же так писать

1 2 3 4
for( const auto& it : map1 ) { cout  "["  it.first  "]"  " "  it.second  endl; }

93 / 93 / 33
Регистрация: 17.03.2012
Сообщений: 536
А у меня показывает 3. Если хотите чтоб ранд каждый раз генерировал случайное число, надо

#include

и в мэйне перед использованием рандома

srand (time(NULL));

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Заполнение контейнера map объектами класса
Здравствуйте! Помогите разобраться с map. Не получается заполнить контейнер объектами класса.

Удаление символа в элементе контейнера map
Доброго времени суток! Есть текстовый файл , его записал в map , остались элементы такого вот рода.

Чтение из файла и заполнение контейнера map
Есть такое задание: дан файл,в котором записаны имена студентов.Напротив каждого имени — их.

Или воспользуйтесь поиском по форуму:

Класс map . Методы изменяющие данные в контейнере

Метод erase() удаляет элемент или группу элементов разными способами. Метод имеет несколько перегруженных реализаций.

2.1. Удаление одного элемента по заданному ключу

Распространенной реализацией метода erase() является удаление элемента на основе заданного ключа. Синтаксис объявления этой реализации следующий

inline size_t erase(const keyType &keyVal);
  • keyType – тип ключа;
  • keyVal – значение ключа.

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод erase() - удалить один элемент по ключу // 1. Сформировать ассоциативный массив mapchar, string> m1; m1.insert(make_pair('A', "Assembler")); m1.insert(make_pair('B', "Bash")); m1.insert(make_pair('C', "C++")); m1.insert(make_pair('D', "Dart")); m1.insert(make_pair('E', "Erlang")); m1.insert(make_pair('F', "Fortran")); // 2. Удалить элементы 'A' и 'D' m1.erase('A'); m1.erase('D'); // 3. Вывести измененный массив mapchar, string>::iterator it = m1.begin(); cout "m1: " while (it != m1.end()) < cout first " : " second >
m1: B : Bash C : C++ E : Erlang F : Fortran
2.2. Удаление одного элемента, на который указывает итератор

В этой реализации метода erase() удаляется один элемент, на который указывает итератор. Синтаксис объявления метода следующий

inline iterator erase(const_iterator Where);
  • Where – константный итератор, указывающий на элемент, который должен быть удален.

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод erase() - удалить один элемент на основе ключа // 1. Сформировать ассоциативный массив mapchar, string> m1; m1.insert(make_pair('A', "Assembler")); m1.insert(make_pair('B', "Bash")); m1.insert(make_pair('C', "C++")); m1.insert(make_pair('D', "Dart")); m1.insert(make_pair('E', "Erlang")); m1.insert(make_pair('F', "Fortran")); // 2. Установить итератор на пару 'F':"Fortran" mapchar, string>::iterator it = m1.find('F'); // 3. Удалить пару m1.erase(it); // 4. Вывести массив cout "m1:" while (it != m1.end()) < cout first " : " second >
m1: A : Assembler B : Bash C : C++ D : Dart E : Erlang
2.3. Удаление нескольких элементов, которые заданы диапазоном

Диапазон определяется итератором начала и итератором конца

inline iterator erase(const_iterator First, const_iterator Last);
  • iterator , const_iterator – тип итератора и константного итератора для текущего контейнера;
  • First – элемент, определяющий начало диапазона удаления;
  • Last – элемент, определяющий конец диапазона удаления. Значение Last указывает на элемент, находящийся за последним удаляемым элементом.

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод erase() - удалить диапазон элементов // 1. Сформировать ассоциативный массив mapint, char> m1; m1.insert(make_pair(1, 'A')); m1.insert(make_pair(2, 'B')); m1.insert(make_pair(3, 'C')); m1.insert(make_pair(4, 'D')); m1.insert(make_pair(5, 'E')); // 2. Вывести массив - тупо, но работает cout for (int i = 0; i < m1.size(); i++) cout " : " // 3. Удалить элементы 2, 3 - литеры 'B', 'C' // 3.1. Объявить итераторы mapint, char>::iterator itFirst; mapint, char>::iterator itLast; // 3.2. Установить итераторы на позиции 2, 3 itFirst = m1.find(2); // установить на ключ 2 itLast = m1.find(4); // установить на ключ 4, который следует за ключом 3 // 3.3. Метод erase - удалить диапазон m1.erase(itFirst, itLast); // 4. Повторно вывести массив с помощью итератора // 4.1. Объявить дополнительный итератор mapint, char>::iterator it = m1.begin(); // 4.2. Непосредственный вывод массива cout "------------------" << endl; cout "m1: " while (it != m1.end()) < cout first " : " >
m1: 1 : A 2 : B 3 : C 4 : D 5 : E ------------------ m1: 1 : A 4 : D 5 : E
3. Метод insert() . Добавить новую пару в массив

Метод insert() добавляет в ассоциативный контейнер новую пару. Метод имеет много перегруженных реализаций. Ниже приведены некоторые из этих реализаций.

3.1. Вставить элементы на основе списка инициализации std::initializer_list

С помощью данной реализации метода insert() сначала создается список инициализации типа std::initializer_list , затем этот перечень передается аргументом в метод insert() . Объявление метода имеет вид

inline void insert(initializer_listpairconst kType, vType>> _llist);
  • kType – тип ключа;
  • vType – тип значения.

Приклад.

#include iostream> #include map> using namespace std; void main() < // Метод insert() - вставить элемент. // Сформировать ассоциативный массив на основе списка инициализации // 1. Создать список инициализации initializer_list pairconst int, string>> ls = < make_pair(1, "One"), make_pair(2, "Two"), make_pair(3, "Three") >; // 2. Создать ассоциативный контейнер mapint, string> m1; // 3. Вставить список инициализации в массив m1.insert(ls); // 4. Вывести массив mapint, string>::iterator it = m1.begin(); // объявить итератор cout while (it != m1.end()) < cout first " : " second >
m1 1 : One 2 : Two 3 : Three
3.2. Добавить пару в контейнер

Чтобы добавить пару key:value в контейнер, используется следующая реализация метода insert()

inline iterator insert(pairkType, vType> &_Val);
  • kType – тип ключа;
  • vType – тип значения;
  • _Val – значение пары.

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод insert() - вставить пару в контейнер // 1. Объявить пустой контейнер строк mapstring, long int> population; // 2. Вставить пару - методы insert() + make_pair() population.insert(make_pair("China", 1.402E9L)); // 3. Вставить пару - использовать объект типа pair pairstring, long int> p("India", 1.38E9L); population.insert(p); // 4. Вставить пару - использовать конструктор типа pair population.insert(pairstring, long int>("USA", 328E6L)); population.insert(pairstring, long int>("Ukraine", 52E6L)); // 5. Вывести новосозданный контейнер mapstring, long int>::iterator it = population.begin(); cout "population:" while (it != population.end()) < cout first " : " second >
population: China : 1402000000 India : 1380000000 USA : 328000000 Ukraine : 52000000
3.3. Вставка диапазона

Данная реализация метода insert() позволяет вставлять целый диапазон пар key:value из ранее сформировавшегося ассоциативного массива. Диапазон задается двумя итераторами. Первый итератор указывает начало диапазона. Второй итератор указывает на элемент, находящийся за последним элементом диапазона, который нужно вставить.

Синтаксис объявления метода

inline void insert(_Iter First, _Iter Last);
  • _Iter – тип итератора;
  • First , Last – итераторы, определяющие диапазон элементов

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод insert() - вставить диапазон элементов // 1. Объявить ассоциативный контейнер mapint, double> m1; // 2. Сформировать контейнер for (int i = 0; i < 10; i++) m1.insert(make_pair(i, i * 1.1)); // 3. Объявить другой ассоциативный контейнер mapint, double> m2; // 4. Сформировать m2 на основе m1, // добавить элементы, которые размещаются в диапазоне [2; 4] // 4.1. Объявить итераторы та установить их на соответвующие позиции mapint, double>::iterator itFirst = m1.find(2); mapint, double>::iterator itLast = m1.find(5); // 4.2. Сформировать m2 m2.insert(itFirst, itLast); // 5. Вывести m2 mapint, double>::iterator it = m2.begin(); cout "m2:" while (it != m2.end()) < cout first " : " second >
m2: 2 : 2.2 3 : 3.3 4 : 4.4
4. Метод swap() . Обменять местами содержимое двух контейнеров

При помощи метода swap() можно обменять содержимое двух контейнеров. Синтаксис объявления метода

inline void swap(mapkType, vType> &_Right);
  • kType – тип ключа;
  • vType – тип значения;
  • _Right – объект класса map , элементы которого обмениваются с элементами вызывающего объекта.

Тип ключа kType и тип значения vType должны совпадать с типами ключа и значения объекта, который вызывает метод swap() .

Пример.

#include iostream> #include map> using namespace std; void main() < // Метод swap() - обменять местами содержимое контейнеров // 1. Создать два контейнера и заполнить их значениями // 1.1. Контейнер m1 mapint, double> m1; m1.insert(make_pair(1, 1.1)); m1.insert(make_pair(5, 5.5)); m1.insert(make_pair(9, 9.9)); // 1.2. Контейнер m2 mapint, double> m2; m2.insert(make_pair(2, 2.2)); m2.insert(make_pair(4, 4.4)); // 2. Обменять местами контейнеры - метод swap() m1.swap(m2); // 3. Вывести контейнер m1 cout "m1:" mapint, double>::iterator it = m1.begin(); while (it != m1.end()) < cout first " : " second  // 4. Вывести контейнер m2 cout "m2:" while (it != m2.end()) < cout first " : " second >
m1: 2 : 2.2 4 : 4.4 m2: 1 : 1.1 5 : 5.5 9 : 9.9
5. Операторная функция operator=() . Присвоить один контейнер другому

С помощью операторной функции operator=() реализуется обычная операция присваивания одного контейнера другому. Синтаксис объявления функции

inline mapkType, vType> operator=(const mapkType, vType> &_Right);
  • kType – тип ключа;
  • vType – тип значения;
  • _Right – объект, размещаемый справа от операции присваивания (контейнер-оригинал). При копировании контейнеров создается полная копия контейнера _Right . Это означает, что после выполнения операции присваивания = оба контейнера размещаются в разных участках памяти.

Пример.

#include iostream> #include map> using namespace std; void main() < // Операторная функция operator=() - присвоить содержимое контейнера другому // 1. Создать контейнер и заполнить его значениями mapint, char> m1; m1.insert(make_pair(1, 'A')); m1.insert(make_pair(2, 'B')); m1.insert(make_pair(3, 'C')); // 2. Создать другой пустой контейнер mapint, char> m2; // 3. Вывести размер другого контейнера cout "m2.size color: #008000;"> // 3. Выполнить присваивание контейнеров m2 = m1; // вызов операторной функции operator=() // 4. Вывести другий контейнер mapint, char>::iterator it = m2.begin(); cout "m2 => "; while (it != m2.end()) < cout "(" first ":" second ") "; it++; > cout // 5. Прибавить к другому контейнеру элемент и повторно вывести его m2.insert(make_pair(4, 'D')); it = m2.begin(); cout "---------------------" << endl; cout "m2 => "; while (it != m2.end()) < cout "(" << (*it).first ":" << (*it).second ") "; it++; > cout // 6. Вывести первый контейнер cout "m1 => "; it = m1.begin(); while (it != m1.end()) < cout "(" first ":" second >
m2.size = 0 m2 => (1:A) (2:B) (3:C) --------------------- m2 => (1:A) (2:B) (3:C) (4:D) m1 => (1:A) (2:B) (3:C)

Как видно из результата, была создана полная копия контейнера m2 в другой области памяти.

Связанные темы

  • Создание контейнера. Конструкторы. Создание пары. Обзор функций и операторов класса
  • Методы, обеспечивающие получение информации из контейнера: at() , begin() , end() , count() , empty() , find() , size() , max_size() , operator[]()

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

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