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

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

  • автор:

Удалить элементы из контейнера 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
Есть такое задание: дан файл,в котором записаны имена студентов.Напротив каждого имени — их.

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

Вставка и удаление элементов из 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 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 дерево ребалансируется, то все итераторы после становятся инвалидными наверное.

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

Особенности языков программирования

В этой статье будет дан обзор библиотеки STL с самого начального уровня, и до продвинутой, весьма полезной в ряде задач, функциональности.

Проще всего начать знакомство с STL со стандартных типов для хранения данных — контейнеров. Каждый раз, когда в программе возникает необходимость оперировать множеством элементов, в дело вступают контейнеры. Контейнер — это практическая реализация функциональности некоторой структуры данных. В языке C (не в C++) существовал только один встроенный тип контейнера: массив. Сам по себе массив имеет ряд недостатков: к примеру, размер динамически выделенного массива невозможно определить на этапе выполнения. Однако основной причиной для более внимательного ознакомления с контейнерами STL является отнюдь не вышеперечисленные недостатки массива. Истинная причина кроется несколько глубже. Дело в том, что в реальном мире структура данных, информацию о которых необходимо хранить, далеко не всегда удачно представима в виде массива. В большинстве случаев требуется контейнер несколько иной функциональности. К примеру, нам может потребоваться структура данных «множество строк», поддерживающая следующие функции:
— добавить строку к множеству;
— удалить строку из множества;
— определить, присутствует ли в рассматриваемом множестве данная строка;
— узнать количество различных строк в рассматриваемом множестве;
— просмотреть всю структуру данных, «пробежав» все присутствующие строки. Конечно, легко запрограммировать тривиальную реализацию функциональность подобной структуры данных на базе обычного массива. Но такая реализация будет крайне неэффективной. Для достижения приемлемой производительности имеет смысл реализовать хэш-таблицу или сбалансированное дерево, но задумайтесь: разве реализация подобной структуры данных (хэш либо дерево) зависит от типа хранимых объектов? Если мы потом захотим использовать ту же структуру не для строк, а, скажем, для точек на плоскости — какую часть кода придётся переписывать заново? Реализация подобных структур данных на чистом C оставляла программисту два пути. 1) Жёсткое решение (Hard-Coded тип данных). При этом изменение типа данных приводило к необходимости внести большое число изменений в самых различных частях кода. 2) По возможности сделать обработчики структуры данных независимыми от используемого типа данных. Иными словами, использовать тип void* везде, где это возможно. По какому бы пути реализации структуры данных в виде контейнера вы не пошли, скорее всего, никто другой ваш код понять, и тем более модифицировать, будет не в состоянии. В лучшем случае другие люди смогут им просто пользоваться. Именно для таких ситуаций существуют стандарты — чтобы программисты могли говорить друг с другом на одном и том же формальном языке. Шаблоны (Templates) в C++ предоставляют замечательную возможность реализовать контейнер один раз, формализовать его внешние интерфейсы, дать асимптотические оценки времени выполнения каждой из операций, а после этого просто пользоваться подобным контейнером с любым типом данных. Можете быть уверены: разработчики стандарта C++ так и поступили. В первой части курса мы на практике познакомимся с основными концепциями, положенными в основу контейнеров C++.

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

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