STL中各種容器的刪除操作

來源:互聯網
上載者:User

在應用中,我們通常不可避免地要對容器中的某些特定元素進行刪除操作。這看起來並不是什麼困難的問題。我們先寫一個迴圈來迭代容器中的元素,如果迭代元素是要刪除的元素,則刪除之。代碼如下所示:

        

vector<int> intContainer;for(vector<int>::iterator is = intContainer.begin(); it != intContainer.end(); ++it){if ( *it == 25) intContainer.erase(it);}

        寫出此代碼的原意是將vector中值為25的元素刪除,但不幸的是,這樣做是錯誤的,這麼做會帶來詭異的未定義行為。因為當一個容器的一個元素被刪除時,指向那個元素的所有迭代器將失效。當intContainer.erase(it)返回時,it已經失效。在for迴圈中對於失效的it執行自增操作,這是一件多麼不靠譜的事情啊。

        既然這樣行不通,那麼我們可以求助於STL提供的remove演算法。藉助remove演算法來達到刪除元素的目的。

vector<int> intContainer;size_t before_size = intContainer.size();remove(intContainer.begin(), intContainer.end(), 25);size_t after_size = intContainer.size();

        運行程式以後發現before_size和after_size是一樣的,說明元素並沒有被真正刪除。寫出以上程式,是處於對remove演算法的不瞭解而致。STL中remove演算法會將不該刪除的元素前移,然後返回一個迭代器,該迭代器指向的是那個應該刪除的元素,僅此而已。所以如果要真正刪除這一元素,在調用remove之後還必須調用erase,這就是STL容器元素刪除的"erase_remove"的慣用法。

vector<int> intContainer;intContainer.erase( remove(intContainer.begin(), intContainer.end(), 25), intContainer.end());


    erase-remove的慣用法適用於連續記憶體容器,比如vector,deque和string,它也同樣適用於list,但是並不是我們推薦的方法,因為使用list成員函數remove會更高效,代碼如下:

list<int> list_int;....list_int.remove(25);

        如果是關聯容器呢?標準關聯容器沒有remove成員函數,使用STL演算法的remove函數時編譯同不過。所以上述remove形式對於標準關聯容器並不適用。在這種情況下,解決辦法就是調用erase:

map<int, int> mapContainer;...mapContainer.erase(25);

        對於標準關聯容器,這樣的元素刪除方式是簡單有效,時間複雜度為O(logn).

        當我們需要刪除的不是某一個元素,而是具備某一條件的元素的時候,我們只需要將remove替換成remove_if即可

bool Is2BeRemove(int value){return value < 25;}vector<int> nVec;list<int> nList;....nVec.erase(remove_if(nVec.begin(), nVec.end(), Is2BeRemove), nVec.end());nList.remove_if(Is2BeRemove);


總結如下

刪除容器中具有特定值的元素:

        如果容器是ector、string或者deque,使用erase-remove的慣用法。如果容器是list,使用list::remove。如果容器是標準關聯容器,使用它的erase成員函數。

刪除容器中滿足某些條件的元素:

        如果容器是ector、string或者deque,使用erase-remove_if的慣用法。如果容器是list,使用list::remove_if。如果容器是標準關聯容器,使用remove_copy_if & swap 組合演算法,或者自己協議個遍曆刪除演算法。

參考資料:李健《編寫高品質C++代碼》第七章,用好STL這個大輪子


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.