今天來**c++中的乙個基礎問題。如何正確地刪除vector
中符合條件的某元素。比如,有乙個vectornums =
,要求刪除nums
中所有值為2的元素。c++初學者可能很快就寫出**:
for (vector::iterator it = nums.begin(); it != nums.end(); it++)
}
這段**迴圈遍歷nums中的每個元素,判斷是否為2,是的話則erase掉。看起來好像沒什麼問題,但是實際上已經造成了bug。這段**的執行完成後,nums儲存的元素是
,值為2的元素並沒有被全部清除掉,這個結果大家可以自己試驗一下。
為什麼會出現這個結果呢?原因就是迭代器失效:在第乙個2被erase掉的時候,it迭代器已經失效了,用它來繼續遍歷vector就會漏掉被刪除元素後面的第乙個元素,導致2沒有被完全清除。迭代器失效的原因與vector的記憶體管理策略有關,比較簡單,網上資料很多,大家可以搜一下看看。這裡我們重點關注如何正確的使用erase
刪除指定元素。
既然在第一次刪除2的時候,迭代器已經失效了,那麼我們可以在失效後,重置迭代器為begin,再次進行遍歷。**如下:
for (vector::iterator it = nums.begin(); it != nums.end();) else
}
這樣寫可以實現我們的需求,且沒有bug。但是如果在工作中真這麼寫,你可能會被同事鄙視死!為什麼呢?因為這段**無謂地增加了時間複雜度,每刪除乙個元素,就要從頭開始遍歷,本來o(n)時間可以搞定的事情,現在卻需要o(n^2)時間。那麼還有沒有更好的方案呢?當然是有的!
查一下c plus plus**,我們發現erase
函式的返回值是指向當前被刪除元素的下乙個元素的迭代器。那麼我們把這個返回值賦值給it
繼續遍歷不就行了?**如下:
for (vector::iterator it = nums.begin(); it != nums.end();) else
}
這段**可以在o(n)的時間內刪除所有值為2的元素了,嗯,這下你的同事應該滿意了!
對於上面這種寫法,新手還有可能寫出其他bug來,比如下面這段**:
for (…)
這段**存在非常嚴重的bug!如果condition1
有一次為真而continue,it又沒有繼續遞增,那麼condition1永遠為真,程式直接就陷入了死迴圈,再也出不來了。這個錯誤要注意避免!
同理,在迴圈中向vector insert或者push_back元素的時候也一定要注意迭代器失效造成的問題。
the end
vector中的元素刪除
在vector中用迭代器刪除元素會用到erase 函式。這個函式返回的是刪除當前元素後下乙個元素的指標,也就是說在刪除元素後,指標指向刪除元素後面的那個,具體用法參考下面 vector iterator itin inliers.begin vector iterator itm matches.b...
使用迭代器從map或vector中刪除元素
std map的迭代器 刪除時只影響當前元素 include stdafx.h include std mapm int main else printf 2 m.len d n m.size return 0 原因分析 it 的操作可拆分為三個步驟 首先把 it 備份一下。把 it 加上1。返回第...
vector中特定元素的刪除
std vector沒有直接刪除特定值元素的成員方法。所以必須使用remove演算法 std vectorcoll remove all elements with value val coll.erase remove coll.begin coll.end val coll.end remove...