erase()函數(shù)的功能是用來刪除容器中的元素
函數(shù)原型:
iterator erase(iterator where);
iterator erase(iterator first,iterator last);
basic_string& erase(size_type p0=0,size_type n=np);
刪除某個(gè)容器里的某個(gè)元素:c.erase(T);
看似一個(gè)簡(jiǎn)單的動(dòng)作,然而對(duì)不同類型的容器,內(nèi)部卻做了截然不同的事情,后面介紹。
假設(shè)有這樣一個(gè)題目,將某個(gè)容器中所有滿足條件N == X的元素刪除,按照常規(guī)的思路應(yīng)該有類似這樣的代碼:
Container<T>::iterator it;
for (it = container.begin(); it != container.end(); ++it) {
if (N == X)
container.erase(it);
}
然而這樣的代碼對(duì)于任一種容器都是錯(cuò)誤的
容器按內(nèi)存分配方式可以分為鏈表容器和數(shù)組容器。
所謂的鏈表容器指的是一種表現(xiàn)方式,包括list、slist等這樣基于節(jié)點(diǎn)的容器(動(dòng)態(tài)分配內(nèi)存塊)和set、map、multiset、multimap等關(guān)聯(lián)容器(平衡樹實(shí)現(xiàn)),而數(shù)組容器指的是在一塊連續(xù)的內(nèi)存上保存元素的連續(xù)內(nèi)存容器,比如vector、deque、string等。
OK,現(xiàn)在說說erase對(duì)他們的操作,鏈表容器以list為例,當(dāng)執(zhí)行container.erase(it)時(shí),確實(shí)第一個(gè)滿足條件的元素刪除了,但這時(shí)it指針已經(jīng)被刪除了,它也不指向任何元素了,所以也只能到此為止了,也就是說上面的代碼對(duì)于鏈表容器來說只能正確刪除第一個(gè)滿足條件的元素,針對(duì)這個(gè)問題我們首先想到的就是在刪除指針之前,給其做個(gè)備份,很好,不錯(cuò)的主意,我們一般采用的方法是建立個(gè)臨時(shí)變量,這個(gè)臨時(shí)變量可以在程序循環(huán)中適當(dāng)?shù)奈恢檬褂茫聪铝写a實(shí)現(xiàn),是將這個(gè)臨時(shí)變量直接建立在erase實(shí)現(xiàn)里,這樣做更簡(jiǎn)潔,也顯得專業(yè)些
(以刪除int型鏈表中所有偶數(shù)為例,也是大家都喜歡的一個(gè)例子):
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
lt.erase(it++);
else
++it;
}
鏈表容器使用erase刪除節(jié)點(diǎn)還有一個(gè)特點(diǎn),就是會(huì)將下一個(gè)元素的地址返回,所以也可以這樣實(shí)現(xiàn):
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
it = lt.erase(it);
else
++it;
}
當(dāng)然用list容器本身提供的算法也是個(gè)不錯(cuò)的主意(掛回調(diào)):
{
return (n % 2 == 0);
}


lt.remove_if(evenNumber);
數(shù)組容器以vector為例,當(dāng)執(zhí)行container.erase(it)時(shí),和上面提到的一樣,第一個(gè)滿足條件的元素刪除了,但這時(shí)數(shù)組容器不允許中間有“空隙”,所以會(huì)做個(gè)大動(dòng)作,就是將被刪元素后面所有的元素前移(參考STL源碼),而數(shù)組容器記錄的是下標(biāo),所以刪除元素后,當(dāng)前下標(biāo)定位的元素也就順理成章的變成了原有隊(duì)列中的下一個(gè)元素,同樣以刪除偶數(shù)為例,代碼如下:
for (it = v.begin(); it != v.end(); ) {
if (*it % 2 == 0)
v.erase(it);
else
++it;
}
也可以使用reverse_iterator迭代器,并且在某些刪除操作中會(huì)有更好的效率(因?yàn)樗鼤?huì)使上面提到的“大動(dòng)作”變小一些):
for ( ; ri != v.rend(); ) {
if (*ri % 2 == 0)
v.erase((++ri).base());
else
++ri;
}


