1. 程式人生 > >C++9.3.7 容器刪除元素--erase、clear、pop_front函式

C++9.3.7 容器刪除元素--erase、clear、pop_front函式

簡介

看一下9.5節容器之間的區別—-list類似於連結串列,容易增刪改,queue是兩端增刪改容易。,所以刪除時,用到最多的容器時list

1.刪除第一個或最後一個元素—–pop_front 和pop_back 函式,函式返回void

2.刪除容器內的一個或一段元素—–erase函式,erase都返回一個迭代器,它指向被刪除的元素後面的元素

3.刪除容器內所有的元素—clear函式

4. 注意:在刪除元素後迭代器會失效,因此一定要對迭代器重新賦值。另外,erase函式返回一個迭代器,指向被刪除元素的下一個元素。因為在for語句頭中要對迭代器加1,所以在if語句中將迭代器減1,以免漏掉需要處理的元素。

===========================================================================================================

一、刪除元素—–queue和list容器

前面提到過使用insert操作在容器的任何位置插入元素,並支援特定的push_back和push_front 操作在容器首部或尾部插入新元素。
類似的,容器提供了erase操作和特定的pop_front和pop_back操作來刪除容器內的元素。

這裡寫圖片描述

1. 刪除第一個或最後一個元素pop_front 和pop_back 函式—list可以,queue也可以

  • pop_front 和pop_back函式用於刪除容器內的第一個和最後一個元素。但vector容器型別不支援pop_front操作。這些操作刪除指定的元素並返回void;

  • pop_front 經常與front操作配套使用,實現以棧的方式處理容器

  • pop_front 和pop_back函式的返回值並不是刪除的元素值,而是void。要獲取刪除的元素值,則必須在刪除元素之前呼叫front或back函式。

while(!ilist.empty()){
   process(ilist.front());//獲取要刪除的元素
   ilist.pop_front();//刪除第一個元素

}

2.刪除容器內的一個或一段元素erase操作—list容器

  • 刪除一個或一段元素更通用的方法是erase操作。

  • 該操作有兩個版本:刪除由一個迭代器指向的單個元素,刪除由一對迭代器標記的一段元素。erase的這兩種形式都返回一個迭代器,它指向被刪除的元素後面的元素。

  • 必須確保用作引數的迭代器或迭代器範圍是有效的。

  • * 通常要在容器中找到要刪除的元素後,才使用erase操作。尋找一個指定元素的最簡單方法是使用標準庫的find演算法。*

  • find演算法在後面的11.1節還會介紹,為了使用find函式或其他泛型演算法,在程式設計時,必須將algorithm標頭檔案包含進來。

  • find函式需要一對標記查詢範圍的迭代器以及一個在該範圍內查詢的值做引數,查詢完成後,該函式返回一個迭代器,它指向具有指定值的第一個元素,或超出末端的下一個位置。

string searchValue("Quasimodo");//定義一個string物件
list<string>::iterator iter=find(slist.begin(),slist.end(),searchValue);
if(iter!=slist.end())
    slist.erase(iter);//是iter,不是*iter
//注意:在刪除元素之前,必須確保迭代器是不是end迭代器。使用erase操作刪除單個元素必須確保該元素確實存在------如果刪除指向超出末端的下一個位置的迭代器,那麼erase操作的行為未定義

3.刪除容器內所有的元素—clear函式

slist.clear();//刪除所有元素
slist.erase(slist.begin(),slist.end());同上

//erase 函式的迭代器對版本提供了刪除一部分元素的功能:
list<string>::iterator elem1,elem2;
elem1=find(slist.begin(),slist.end(),val1);//elem1指向val1
elem2=find(elem1,slist.end(),val2);//elem2指向val2
slist.erase(elem1,elem2);//刪除elem1到elem2之間的所有元素,但不包括elem2指向的元素
  • erase、pop_front、pop_back函式使指向被刪除元素的所有迭代器失效。對於vector容器,指向刪除點後面的元素的迭代器通常也會失效,而對於queue容器,如果刪除時不包括第一個元素或最後一個元素,那麼deque容器相關的所有迭代器都會失效
//習題9.25
//需要刪除一段元素時,如果val1和val2相等,那麼程式會怎樣?其中一個不存在,程式會怎樣?

//解答
//相等,那麼不會刪除任何元素。
//其中一個不存在,或兩個都不存在,則會發生執行錯誤。
//習題9.26

#include <iostream>
#include<string>
#include<cctype>
#include<vector>
#include<list>

using namespace std;
int main()
{

int ia[]={0,1,1,2,3,4,5,8,13,21,55,89};
vector<int> ivec(ia,ia+11);
list<int> ilst(ia,ia+11);

for(list<int>::iterator lit=ilst.begin();lit!=ilst.end();lit++){

if(*lit%2!=0)
{
    lit=ilst.erase(lit);//刪除元素
    --lit;
}
cout<<*lit;
}

cout<<endl;
for(vector<int>::iterator vit=ivec.begin();vit!=ivec.end();vit++){

if(*vit%2==0)
{
    vit=ivec.erase(vit);//刪除元素
    --vit;//迭代器重新賦值,進行回退,指向被刪除元素的前一個元素。
}
cout<<*vit;
}

    return 0;
}

注意:在刪除元素後迭代器會失效,因此一定要對迭代器重新賦值。另外,erase函式返回一個迭代器,指向被刪除元素的下一個元素。因為在for語句頭中要對迭代器加1,所以在if語句中將迭代器減1,以免漏掉需要處理的元素。