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

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

  • автор:

Как удалить элемент из 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 решения (ветка "Работа с каталогами в си"). Если стандарт тяжело воспринимать, посмотри Страуструпа, это фактически тот же стандарт, написанный более человеческим языком.

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

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 - базовый класс, также есть наследуемый от.

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

Yhlas_Y → Favourite problem

islamicTerrorist69 → Facing problem in dynamic programming

SilverSurge → CSES Range Queries: Polynomial Queries

127.0.0.1 → Codeforces Round 907 (Div. 2)

_thor__ → Codeloop 2023: A Knockout Tournament Based Coding Contest

Yhlas_Y → IDE for cp

MikeMirzayanov → Please, read this

Imakf → Codeforces Round 906 Editorial

noomaK → IEEEXtreme 17.0 Problems Discussion

chenjb → Rescheduling of World Finals 22&23

anmolsainiii23 → Confused Regarding Cses 2nd DP Question

-kirito- → TheForces Round #25 Editorial

stdfloat → Is CF enough for IZHO, IOI?

DeadPixel99 → Help needed!

Vladosiya → Codeforces Command Lines (2023-10-06)

-kirito- → Invitation to TheForces #25 (5^2-Forces, TheForces-Rated, Prizes!)

one_autum_leaf → Find the number of rectangles of same color in a matrix

ryuukumar → What to learn to solve 1300 rated questions?

Imakf → Codeforces Round 906 (Div. 1, Div. 2)

74TrAkToR → Codeforces Round #904 (Div. 2) Editorial

whynesspower → Reverse check the questions: ChatGPT

aryang22 → Perhaps you should wait a little before giving up.

Alpha_Info → Listen to music?

_Firdavs_Aminov_ → Dark theme Codeforces

sarthakjoleya → Need Help for my Sorting Visualizer

Как удалить элемент из 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++);

прога ваще падает;)

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

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

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