Как удалить элемент из 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 дерево ребалансируется, то все итераторы после становятся инвалидными наверное.
подскажите, как все таки удалить нужноые мне элементы?
Сообщ. #2 , 29.05.07, 17:04
Рейтинг (т): 172
Сплагиатил код у Джосатиса
for(pos = coll.begin(); pos != coll.end();)
if(pos -> second == value)
coll.erase(pos++);
Условие сам поменяешь
Сообщ. #3 , 29.05.07, 17:58
Рейтинг (т): 225
Цитата byte @ 29.05.07, 17:04
coll.erase(pos++);
имхо нужно
pos = coll.erase(pos);
после erase все итераторы становятся невалидными(кроме возвращенного самим erase)
Сообщение отредактировано: archimed7592 — 29.05.07, 17:59
Сообщ. #4 , 29.05.07, 18:26
Рейтинг (т): 723
Цитата archimed7592 @ 29.05.07, 17:58
после erase все итераторы становятся невалидными(кроме возвращенного самим erase)
Нет. У map::erase инвалидируется только итератор, по которому удаляется элемент.
Добавлено 29.05.07, 18:27
Цитата 23.1.2 — Associative containers
The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.
Сообщ. #5 , 30.05.07, 17:15
Рейтинг (т): 34
Цитата archimed7592 @ 29.05.07, 17:58
pos = coll.erase(pos)
так делал вначале. erase возвращает void. так что не прокатит;)
Цитата byte @ 29.05.07, 17:04
coll.erase(pos++);
прога ваще падает;)
переделал дизайн слегка. теперь просто заношу ключи элементов, которые нужно удалить, в списочек, а потом прохожусь по списку, ищу элемент по ключу и удаляю
Как удалить элемент из map c
Здравствуйте, уважаемые знатоки C++.
Нужно удалять элементы из std::map согласно некотому условию. Всегде ли будет работать такой трюк:
std::map m; std::map::iterator cur, end; cur = m.begin(); end = m.end(); while (cur != end) < if (is_not_OK(*cur)) m.erase(cur++); else ++cur; >
Re: удаление элементов из std::map
| От: | Bell | |
| Дата: | 02.05.07 13:53 | |
| Оценка: | 6 (1) -1 | |
Здравствуйте, sigsegv, Вы писали:
S>Здравствуйте, уважаемые знатоки C++.
S>Нужно удалять элементы из std::map согласно некотому условию. Всегде ли будет работать такой трюк:
Да, это стандартный прием.
Любите книгу — источник знаний (с) М.Горький
Re[2]: удаление элементов из std::map
| От: | Sk0rp | |
| Дата: | 02.05.07 15:30 | |
| Оценка: | 1 (1) -2 | |
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, sigsegv, Вы писали:
S>>Здравствуйте, уважаемые знатоки C++.
S>>std::map m; S>>std::map::iterator cur, end; S>>cur = m.begin(); S>>end = m.end(); S>>while (cur != end) S>>< S>> if (is_not_OK(*cur)) S>> m.erase(cur++); > else S>> ++cur; S>>>
S>>Нужно удалять элементы из std::map согласно некотому условию. Всегде ли будет работать такой трюк:
B>.
B>Да, это стандартный прием.
не согласен, при удалении может в общем случае произойти реаллокация и итератор станет абсолютно невалидным.
стандартный прием это воспользоваться тем, что erase возвращает итератор на следующий после последнего удаленого элемент:
while(cur != m.end()) < if(is_not_OK(*cur)) cur = m.erase(cur); else ++cur; >
заранее запомненный m.end() также скорее всего окажется невалидным.
Re[3]: удаление элементов из std::map
| От: | Bell | |
| Дата: | 02.05.07 15:42 | |
| Оценка: | 1 (1) | |
Здравствуйте, Sk0rp, Вы писали:
S>не согласен, при удалении может в общем случае произойти реаллокация и итератор станет абсолютно невалидным.
Ассоциативные контейнеры не попадают в этот «общий случай»:
23.1.2/8
The insert members shall not affect the validity of iterators and references to the container,
and the erase members shall invalidate only iterators and references to the erased elements.
Еще раз обращаю внимание на конструкцию
m.erase(cur++);
Т.е. после вызова erase у нас остается валидный итератор.
Подробнее можно посмотреть в поиске.
S>стандартный прием это воспользоваться тем, что erase возвращает итератор на следующий после последнего удаленого элемент:
S>
S>while(cur != m.end()) S> < S>if(is_not_OK(*cur)) S> cur = m.erase(cur); S> else S> ++cur; S>> S>
Операция erase для ассоциативных контейнеров по стандарту возвращает void — смотри таблицу 69 в 23.1.2/7. То, что реализация STL от Dinkumware (поставляется с MSVC) возвращает итератор, вовсе не означает, что другие реализации делают так же.
S>заранее запомненный m.end() также скорее всего окажется невалидным.
смотри выше.
Итого имеем 3 неверных утверждения из трех
Любите книгу — источник знаний (с) М.Горький
Re[4]: удаление элементов из std::map
| От: | Константин Л. |
| Дата: | 02.05.07 15:54 |
| Оценка: |
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Sk0rp, Вы писали:
S>>не согласен, при удалении может в общем случае произойти реаллокация и итератор станет абсолютно невалидным.
B>Ассоциативные контейнеры не попадают в этот "общий случай":
B>
B>23.1.2/8
B>The insert members shall not affect the validity of iterators and references to the container,
B>and the erase members shall invalidate only iterators and references to the erased elements.
B>Еще раз обращаю внимание на конструкцию
B>
B>m.erase(cur++);
B>Т.е. после вызова erase у нас остается валидный итератор.
B>Подробнее можно посмотреть в поиске.
Эти 2 предложения противоречивы. Разве нет?
Re[4]: удаление элементов из std::map
| От: | Sk0rp | |
| Дата: | 02.05.07 16:37 | |
| Оценка: | -1 | |
Здравствуйте, Bell, Вы писали:
B>Операция erase для ассоциативных контейнеров по стандарту возвращает void — смотри таблицу 69 в 23.1.2/7. То, что реализация STL от Dinkumware (поставляется с MSVC) возвращает итератор, вовсе не означает, что другие реализации делают так же.
map::erase
Removes an element or a range of elements in a map from specified positions or removes elements that match a specified key.
iterator erase( iterator _Where ); iterator erase( iterator _First, iterator _Last ); size_type erase( const key_type& _Key );
Parameters
_Where
Position of the element to be removed from the map.
_First
Position of the first element removed from the map.
_Last
Position just beyond the last element removed from the map.
_Key
The key value of the elements to be removed from the map.
Return Value
For the first two member functions, a bidirectional iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the map if no such element exists.
For the third member function, returns the number of elements that have been removed from the map.
Send feedback on this topic to Microsoft
© 1992-2002 by P. J. Plauger. All rights reserved.
© Microsoft Corporation. All rights reserved.
Re[5]: удаление элементов из std::map
| От: | . | |
| Дата: | 02.05.07 16:50 | |
| Оценка: | 1 (1) | |
Здравствуйте, Константин Л., Вы писали:
КЛ>Эти 2 предложения противоречивы. Разве нет?
Нет. Я тоже как-то ошибся на этом.
m.erase(cur++) означает: создать временную копию cur, увеличить значение cur (он становится указывающим на следующий элемент), передать временную копию в erase, удаляется текущцй элемент, грохнуть временную копию. В итоге cur становтся указывающим на следующий элемент, невалидный итератор "забыт", элемент удалён.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: удаление элементов из std::map
| От: | ShaggyOwl | http://www.rsdn.org |
| Дата: | 02.05.07 17:13 | |
| Оценка: |
Здравствуйте, Sk0rp, Вы писали:
B>>Операция erase для ассоциативных контейнеров по стандарту возвращает void — смотри таблицу 69 в 23.1.2/7. То, что реализация STL от Dinkumware (поставляется с MSVC) возвращает итератор, вовсе не означает, что другие реализации делают так же.
S>Send feedback on this topic to Microsoft
S>© 1992-2002 by P. J. Plauger. All rights reserved.
S>© Microsoft Corporation. All rights reserved.
Если собирать следующий пример с STLPort
std::mapint, int> m; std::mapint, int>::iterator it = m.begin(); it = m.erase( it );
На третьей строки имеем
Хорошо там, где мы есть! 🙂
Re: удаление элементов из std::map
| От: | latemic |
| Дата: | 02.05.07 19:12 |
| Оценка: |
Здравствуйте, sigsegv, Вы писали:
S>Здравствуйте, уважаемые знатоки C++.
S>Нужно удалять элементы из std::map согласно некотому условию. Всегде ли будет работать такой трюк:
Да такой трюк будет работать всегда. Достаточно посмотреть реализацию операции постфиксного инкремента для итератора:
iterator& operator++() < // preincrement ++(*(const_iterator *)this); return (*this); > iterator operator++(int) < // postincrement iterator _Tmp = *this; ++*this; return (_Tmp); >
Этот код демонстрирует, что операция постфиксного инкремента возвращает копию объекта, которая станет аргуменитом метода map::erase(), в то время как оригинальный объект будет уже другим.
"Если нельзя, но очень хочется. то можно"
Re[5]: удаление элементов из std::map
| От: | Bell |
| Дата: | 02.05.07 20:19 |
| Оценка: |
Здравствуйте, Sk0rp, Вы писали:
S>map::erase
S>Removes an element or a range of elements in a map from specified positions or removes elements that match a specified key.
S>© 1992-2002 by P. J. Plauger. All rights reserved.
S>© Microsoft Corporation. All rights reserved.
Я знаю что написано в MSDN по этому поводу. Именно это я и имел ввиду:
B>>Операция erase для ассоциативных контейнеров по стандарту возвращает void — смотри таблицу 69 в 23.1.2/7. То, что реализация STL от Dinkumware (поставляется с MSVC) возвращает итератор, вовсе не означает, что другие реализации делают так же.
Однако не нужно забывать, что существует еще стандарт языка и его стандартной библиотеки, и многие реализации этому стандарту следуют.
Любите книгу — источник знаний (с) М.Горький
Re[5]: удаление элементов из std::map
| От: | Константин Л. |
| Дата: | 03.05.07 08:49 |
| Оценка: |
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, Bell, Вы писали:
B>>Здравствуйте, Sk0rp, Вы писали:
S>>>не согласен, при удалении может в общем случае произойти реаллокация и итератор станет абсолютно невалидным.
B>>Ассоциативные контейнеры не попадают в этот "общий случай":
B>>
B>>23.1.2/8
B>>The insert members shall not affect the validity of iterators and references to the container,
B>>and the erase members shall invalidate only iterators and references to the erased elements.
B>>Еще раз обращаю внимание на конструкцию
B>>
B>>m.erase(cur++); >
КЛ>B>Т.е. после вызова erase у нас остается валидный итератор.
B>>Подробнее можно посмотреть в поиске.
КЛ>Эти 2 предложения противоречивы. Разве нет?
ааа, тут же постинкремент
КЛ>[]
Re[5]: удаление элементов из std::map
| От: | Андрей Коростелев | http://www.korostelev.net/ |
| Дата: | 03.05.07 09:56 | |
| Оценка: |
Здравствуйте, Sk0rp, Вы писали:
B>>То, что реализация STL от Dinkumware (поставляется с MSVC) возвращает итератор, вовсе не означает, что другие реализации делают так же.
S>map::erase
S>Removes an element or a range of elements in a map from specified positions or removes elements that match a specified key.
Поясню, почему тебе лепят минусы. Как упомянуто в правилах форума
Автор: Павел Кузнецов
Дата: 25.03.03
, тут отсуждаются технические аспекты использования языков C, C++ и C++/CLI в том виде, как они определены соответствующими стандартами.
Ты же ссылаешься на документацию (MSDN), поставляемую разработчиком конкретного компялятора (MSVC), или же предлагаешь system-specific решения (ветка "Работа с каталогами в си"). Если стандарт тяжело воспринимать, посмотри Страуструпа, это фактически тот же стандарт, написанный более человеческим языком.
Вставка и удаление элементов из 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,552 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
venti → Why do you compete?
Geo_Is_Bad_By_Ileonov → эта олпрога просто имба
maomao90 → CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)
FHVirus → [Tutorial] How to get (almost) unlimited grid paper during contest.
![]()
abcsumits → TLE on python code on the problem after having same complexity as of other right submitions
Imakf → Codeforces Round 906 Editorial
sahaun → Advent of Code 2023 starts in a week!
awoo → Educational Codeforces Round 158 [рейтинговый для Div. 2]
![]()
flamestorm → Codeforces Round #817 (Div. 4) Editorial
![]()
ABalobanov → Contest in gym 2
![]()
awoo → Разбор Educational Codeforces Round 120
![]()
FelixMP → CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!) Editorial
codepasta → Solution to A+B Problem
thanhdno → DSU applications
Bobrovin → Почему у задач с контестов 390-399 нет рейтинга?
lukameladze1 → [Tutorial] Edge centroid decomposition & other techniques
![]()
faiyaz26 → Update query on Mo's Algorithm
Medeali → Finally Pupil
pikamonstruosa → Love you tourist!
Minilek → Free trip to Ethiopia or Jamaica to teach algorithms
![]()
MikeMirzayanov → Изменение правил об использовании стороннего кода в соревнованиях Codeforces
![]()
E869120 → [Tutorial] A way to Practice Competitive Programming : From Rating 1000 to 2400+
SecondThread → Hacker Cup Shirts 2023
gurnam771 → Poor Pigs modification
![]()
Balajiganapathi → Codeforces problem recommender
