Kako ukloniti elemente iz spremnika uobičajeno je pitanje za C ++ intervju, tako da ako pažljivo pročitate ovu stranicu možete zaraditi nekoliko bodova.
Idiom brisanja i uklanjanja tehnika je C ++ za uklanjanje elemenata koji ispunjavaju određeni kriterij iz spremnika. Međutim, moguće je eliminirati elemente tradicionalnom ručno napisanom petljom, ali idiom brisanja i uklanjanja ima nekoliko prednosti.
Usporedba
// Using a hand-written loop std::vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; for (auto iter = v.cbegin(); iter < v.cend(); /*iter++*/) { if (is_odd(*iter)) { iter = v.erase(iter); } else { ++iter; } } // Using the erase–remove idiom std::vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; v.erase(std::remove_if(v.begin(), v.end(), is_odd), v.end());
Kao što vidite, kod s ručno napisanom petljom zahtijeva malo više tipkanja, ali ima i problema s izvedbom. Svaki erase
poziv mora pomaknuti prema naprijed sve elemente nakon izbrisanog, kako bi se izbjegle "praznine" u zbirci. Pozivanje erase
više puta na isti spremnik generira puno dodatnih troškova premještanja elemenata.
S druge strane, kod s idiomom za brisanje i uklanjanje ne samo da je izražajniji, već je i učinkovitiji. Prvo upotrebljavate remove_if/remove
za premještanje svih elemenata koji ne odgovaraju kriterijima uklanjanja na prednju stranu raspona, zadržavajući relativni redoslijed elemenata. Dakle, nakon poziva remove_if/remove
, jednim pozivom erase
brišu se svi preostali elementi na kraju raspona.
Primjer
#include // the general-purpose vector container #include // cout #include // remove and remove_if bool is_odd(int i) { return (i % 2) != 0; } void print(const std::vector &vec) { for (const auto& i : vec) std::cout << i << ' '; std::cout << std::endl; } int main() { // initializes a vector that holds the numbers from 1-10. std::vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; print(v); // removes all elements with the value 5 v.erase(std::remove(v.begin(), v.end(), 5), v.end()); print(v); // removes all odd numbers v.erase(std::remove_if(v.begin(), v.end(), is_odd), v.end()); print(v); // removes multiples of 4 using lambda v.erase(std::remove_if(v.begin(), v.end(), [](int n) { return (n % 4) == 0; }), v.end()); print(v); return 0; } /* Output: 1 2 3 4 5 6 7 8 9 10 1 2 3 4 6 7 8 9 10 2 4 6 8 10 2 6 10 */
Izvori
“Izbriši – ukloni idiom” Wikipedia: Slobodna enciklopedija. Wikimedia Foundation, Inc. en.wikipedia.org/wiki/Erase-remove_idiom
Meyers, Scott (2001.). Učinkovit STL: 50 specifičnih načina za poboljšanje upotrebe standardne biblioteke predložaka. Addison-Wesley.