STL中remove 和erase 的用法

2021-09-25 06:39:20 字數 1836 閱讀 9651

示例:

initializer_listlist_t = ;

vectorvec(list_t);

vector::iterator it;

for (it = vec.begin(); it != vec.end(); ++it)

cout << endl;

remove(vec.begin(), vec.end(), 1);

for (it = vec.begin(); it != vec.end(); ++it)

cout << endl;

輸出結果為:

1 2 1 3 4 1 5 6 7 8

2 3 4 5 6 7 8 6 7 8

呼叫remove()函式後,容器中的元素個數並沒有減少,會發現多出3個元素6,7,8。因為remove()並不是真正的刪除元素,而是用後面的元素代替刪除元素。也就是說,當刪除第乙個1時,用2來代替1,刪除第二個1時,用3來代替,以此類推。所以多出來的那3個元素沒有被刪除。

示例:

initializer_listlist_t = ;

vectorvec(list_t);

vector::iterator it;

for (it = vec.begin(); it != vec.end(); ++it)

cout << endl;

vec.erase(remove(vec.begin(), vec.end(), 1), vec.end());

for (it = vec.begin(); it != vec.end(); ++it)

cout << endl;

輸出結果為:

1 2 1 3 4 1 5 6 7 8

2 3 4 5 6 7 8

在vector中有三種涉及刪除的方法,第一種是vector::clear(),第二種是vector::erase(),第三種是vector::pop_back()。clear用來清空整個vector,同時將size變成0,無返回值;erase通過傳入迭代器進行刪除,既可以刪除單個元素,也可以刪除某一範圍的元素,刪除之後它將返回下乙個位置的迭代器;pop_back用來刪除末尾元素,同時將size減1,無返回值。

一般來講erase用得比較多,不注意也容易踩坑,例如:

vectorvec;

for(auto it = vec.begin(); it != vec.end(); it++)

}

這個**如果不在for迴圈裡加上最後的判斷會導致錯誤,原因在於,當it指向最後乙個2時,滿足刪除條件,刪除後it變成了end,然後又做了++操作,導致越界。

類似的坑還有許多,這裡就不一一枚舉了,總之,它們的共同點在於對vector進行刪除時都不夠優雅,需要進行一些額外的處理避免誤操作。

事實上,我們完全可以使用提供的remove和remove_if方法,配合erase進行刪除。這兩個方法並不是真的刪除元素,而是以覆蓋的方式將滿足刪除條件的元素移到容器最後(它們具體的實現方式很有意思,但是這裡從略,總之有兩點:1)它們並沒有真的刪除元素;2)它們使用了「覆蓋」的方式,將要刪除的元素移到最後,因此這些元素可能因為被覆蓋過而發生改變,但這已經不重要了),然後返回指向第乙個要刪除位置的迭代器。這樣一來,刪除就優雅多了,例如:

vec.erase(remove(vec.begin(), vec.end(), 3), vec.end());
如果再用上lambda,看起來會更酷:

vec.erase(remove_if(vec.begin(), vec.end(), (int x)), vec.end());

STL中的remove問題

我將從remove的複習開始這個條款,因為remove是stl中最糊塗的演算法。誤解remove很容易,驅散所有關於remove行為的疑慮 為什麼它這麼做,它是怎麼做的 是很重要的。這是remove的宣告 templateforwarditerator remove forwarditerator ...

STL 中 remove 的運用

by a code rabbit 今天在看別人的解題報告時,發現這麼一行 remove pack 0 pack strlen pack 0 刪除行中的空格頓時想起前幾天寫的乙個函式 void filterspaces char expression new,char expression pos e...

STL中的remove問題

我將從remove的複習開始這個條款,因為remove是stl中最糊塗的演算法。誤解remove很容易,驅散所有關於remove行為的疑慮 為什麼它這麼做,它是怎麼做的 是很重要的。這是remove的宣告 templateforwarditerator remove forwarditerator ...