STL中謹慎選擇刪除元素的方法,stl謹慎選擇

來源:互聯網
上載者:User

STL中謹慎選擇刪除元素的方法,stl謹慎選擇


一、要刪除容器中有特定值的所有對象

1、如果容器是vector、string或deque,則使用erase-remove習慣用法。例如:
vector<int> c;

c.erase(remove(c.begin(),c.end(),1963),c.end());//刪除值是1963的元素

下面講一下演算法remove:

template<classForwardIterator,class T>

ForwardIteratorremove(ForwardIterator first,ForwardIterator last,const T& value)

{

   first = find(first,last,value);

   ForwardIterator next = first;

return first ==last?first:remove_copy(++next,last,first,value);

}

template<classInputIterator,class OutputIterator,class T>

OutputIteratorremove_copy(InputIterator first,InputIterator last,OutputIterator result,constT& value)

{

   for(;first != last;++first)

   if (*first != value)

   {

       *result = *first;

       ++result;

}

return result;

}

移除[first,last)之中所有與value相等的元素。這一演算法並不真正從容器中刪除那些元素(換句話說容器大小並為改變),而是將每一個不與value相等(也就是我們並不打算移除)的元素輪番賦值給first之後的空間。返回值標示出重新整理後的最後元素的下一位置。例如序列{0,1,0,2,0,3,0,4},如果我們執行remove(),希望移除所有0值元素,執行結果將是{1,2,3,4,0,3,0,4}。每一個與0不相等的元素,1,2,3,4,分別被拷貝到第一、二、三、四個位置上。第四個位置以後不動,換句話說是第四個位置之後是這一演算法留下的殘餘資料。返回值ForwardIterator指向第五個位置。如果要刪除那些殘餘資料,可將返回的迭代器交給區間所在之容器的erase()成員函數。注意,array不適合使用remove()和remove_if(),因為array無法縮小尺寸,導致殘餘資料永遠存在。對array而言,較受歡迎的演算法是remove_copy()和remove_copy_if()。

remove_copy移除[first,last)區間內所有與value相等的元素。它並不真正從容器中刪除那些元素,而是將結果複製到一個以result標示起始位置的容器身上。新容器可以和原容器重疊,但如果對新容器實際給值時,超越了舊容器的大小,會產生無法預期的結果。返回值OutputIterator指出被複製的最後元素的下一位置。

2、如果容器是list,則使用list::remove。例如:

list<int> c;

c.remove(1963);//該成員函數無返回值

3、如果容器是一個標準關聯容器,則使用它的erase成員函數。例如:

map<int,int>c;

c.erase(1963);//刪除鍵值是1963的元素

對於標準關聯容器使用任何名為remove的操作都是完全錯誤的。這樣的容器沒有名為remove的成員函數,使用remove演算法可能會覆蓋容器的值,同時可能會破壞容器。

二、要刪除容器中滿足特定判別式(條件)的所有對象

1、如果容器是vector、string或deque,則使用erase-remove_if習慣用法。例如我們不再從c中刪除所有等於特定值的元素,而是刪除使下面的判別式返回true的每一個對象:

bool badvalue(int);

c.erase(remove_if(c.begin(),c.end(),badvalue),c.end());

2、對於list,則使用list::remove_if。例如:

c.remove_if(badvalue);

3、如果容器是一個標準關聯容器,則使用remove_copy_if和swap,或者寫一個迴圈來遍曆容器中的元素,記住當把迭代器傳給erase時,要對它進行尾碼遞增。例如:

AssocContainer<int>c;

AssocContainer<int>goodvalues;

Remove_copy_if(c.begin(),c.end(),inserter(goodvalues,goodvalues.end()),badvalue);

c.swap(goodvalues);

或者

AssocContainer<int>c;

for(AssocContainer<int>::iteratori = c.begin();i != c.end();)

{

   if(badvalue(*i))

       c.erase(i++);

   else

       ++i;

}

三、要在迴圈內部做某些(除了刪除對象之外的)操作:

1、如果容器是一個標準序列容器,則寫一個迴圈來遍曆容器中的元素,記住每次調用erase時,要用它的返回值更新迭代器。例如:
ofstream logFile;

SeqContainer<int>c;

for (SeqContainer<int>::iteratori = c.begin();i != c.end();)

{

   if (badvalue(*i))

   {

       logFile << “Erasing” << *i<< ‘\n’;

       i = c.erase(i);//把erase的返回值賦給i,使i的值保持有效

}

else

{

   ++i;

}

}

2、如果容器是一個標準關聯容器,則寫一個迴圈來遍曆容器中的元素,記住當把迭代器傳給erase時,要對迭代器做尾碼遞增。例如:

ofstream logFile;

AssocContainer<int>c;

for(AssocContainer<int>::iterator i = c.begin();i != c.end();)

{

   if (badvalue(*i))

{

   logFile<< “Erasing ” << *i << ‘\n’;

   c.erase(i++);

}

else

++i;

}


c++ stl中堆操作怎刪除元素

只能重建堆。堆的特性就是這樣,只能在堆頂操作。
如果你真的需要時常在中間刪掉元素,你根本不應該選擇使用堆。
 
C++中STL各種移除元素方法

容器c
當c是vector、string、或deque時,用
c.erase( remove( c.begin(), c.end(), 1963 ), c.end() );//移除c中值是1963的元素

當c是list時,用
c.remove(1963);

當c是關聯容器時,用
c.erase(1963);
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.