Dneska se podíváme na to, jak zjednodušit odstraňování prvků z kontejneru v C++.
Původní kód
Mějme následující kód:
std::map<int, int> m; // ... if (m.find(key) != m.end()) { m.erase(key); }
Nejdříve si zjistíme, zda daný prvek v mapě existuje, a pokud ano, tak jej odstraníme.
Proč takto ne?
Kód výše vlastně dělá toto:
if (/* zjisti pozici prvku v mapě a zahoď ji */) { /* nalezni ji znovu a zruš prvek, který se na této pozici nachází */ }
Pokud daný klíč v mapě existuje, tak se daná mapa prohledá dvakrát.
Jak to udělat lépe?
m.erase(key);
Je zbytečné zjišťovat, zda se daný prvek v mapě nachází, protože std::map::erase()
to musí tak či tak ověřit, aby mohla vrátit buď 1 či 0. Mapa se pak prohledá právě jednou.
Poznámky na závěr
- Samozřejmě, místo
std::map
si můžete představit libovolný jiný kontejner. - Tento tip souvisí s tipem jak získat prvek z kontejneru po ověření jeho existence v C++.
Někdy se však find hodí -
Někdy se však find hodí - např. potřebujeme před smazáním hodnotu mazaného prvku. Můžeme využít erase s iterátorem, který má konstantní složitost. Takovýto erase vrací iterátor na další prvek (to se dá využít při iteraci přes kolekci s mazáním některých prvků) - https://gist.github.com/vojtarylko/5c3244b82ef05b4998a1
Re: Někdy se však find hodí -
Díky za tip. Můj příspěvek byl zaměřen na zbytečnost vyhledání prvku, pokud nám jde pouze o jeho zrušení. Vídávám to dost častu v kódu.