2010-07-19 168 views
4

我有std::listBananas,我想擺脫壞的。有沒有相對簡單的方法來執行下面的僞代碼?C++從列表中刪除列表時,迭代列表

foreach(Banana banana in bananaList) 
{ 
    if(banana.isBad()) bananaList.remove(banana); 
} 

(製作從C#和Java和C++的轉變一直是顛簸的道路。)

+1

http://stackoverflow.com/questions/1038708/erase-remove-contents-from-the-map-or-any-other-stl-container-while-iterating – YuppieNetworking 2010-07-19 20:31:13

+0

@YuppieNetworking:鏈接的問題在一般情況下,但沒有最好的解決方案的OP的情況下 - 他想刪除一個元素,如果一個成員函數返回true。 – 2010-07-19 20:32:35

回答

7
bananaList.remove_if(std::mem_fun_ref(&Banana::isBad)); 

注意,你或許應該使用的std::vector代替std::list雖然 - 99.9 vector性能更好%的情況下,它更容易處理。

編輯:如果您使用的載體,載體不具有的remove_if的成員函數,所以你必須在命名空間std使用純remove_if

bananaVector.erase(
    std::remove_if(bananaVector.begin(), bananaVector.end(), std::mem_fun_ref(&Banana::isBad)), 
    bananaVector.end()); 
+0

真的嗎?我認爲如果我從列表中間刪除了很多東西,那麼'std :: list'就是要走的路。 – JnBrymn 2010-07-19 20:31:59

+0

@John:'std :: list'使得移除本身很快(O(1)),但找到正確的點相對較慢(O(N),通常比矢量的常數更高)。 – 2010-07-19 20:33:08

+2

@John:由於更好的緩存局部性,實際上'std :: vector'在理論上'std :: list'的地方經常表現得更好。你必須測量。 – sbi 2010-07-19 20:34:11

1

你通常會做這樣的事情:

list.erase(std::remove_if(list.begin(), list.end(), std::mem_fun(Banana::isBad)), list.end()); 

編輯:感謝remove_if被實現爲std::list一個成員函數,比利·奧尼爾的回答可能是更好的方式來做到所描述的工作,儘管這會更容易便利着想rt何時/如果您決定使用vector,deque等等,正如已經在評論中討論的那樣,這可能是一件好事。

+0

+1指向我的答案:P – 2010-07-19 20:44:28

0

您可以使用自制軟件類似的代碼

for(list<...>::iterator it=bananas.begin(); end=bananas.end(); it!=end;) { 
    if(... decide ...) { 
    it=bananas.erase(it); 
    } else 
    ++it; 
} 

,或者您可以使用list::remove_if方法,或std::remove_if功能(這是一個vector可用的,太)。

+0

應該總是喜歡顯式循環的算法。 – 2010-07-19 20:44:57