STL序列式容器中刪除元素的方法和陷阱(二)

2021-05-12 23:22:17 字數 3052 閱讀 1150

2.使用stl中通用演算法或容器成員函式刪除元素的方法

以上手工編寫for迴圈**刪除容器中元素的方法也有一些問題,如果判斷條件特別複雜,又有迴圈判斷的話,迴圈中間又有異常處理的話,++itvect的位置就要小心放置了,稍不留意就要出錯。所以手工編寫**刪除容器中元素的方法不太安全,**重複,也不夠優雅,要注意的地方很多。

對於這種情況,可以考慮使用stl中通用演算法remvoe()和remove_if()幫忙。而remvoe()和remove_if()這兩個演算法也有乙個問題需要程式設計師特別小心。在通用演算法中的 remove(包括remove_if) 函式,並不真正從容器中刪除元素,而是「應被刪除的元素」被其後的「未被刪除的元素」覆蓋。返回值forwarditerator指向經移除後的最後元素的下一位置。如vector,執行remove(),希望移除所有值為3的元素,結果為,返回值forwarditerator指向第5個元素。即:

0 1 2 3 3 4 移除前

0 1 2 4 3 4 移除後

移除值為3的元素。移除後3被其後的4替代,最後兩位元素為殘餘資料。

例 5:

void main()

}remove( vectint.begin(), vectint.end(), 3 );

cout << " after deleted , size = " << vectint.size() << endl;

for ( i = 0; i < vectint.size();; i++ )

}執行結果為:

after deleted , size = 6 // 從這行可以看出,移除後容器的大小沒變

i = 0 , 0

i = 1 , 1

i = 2 , 2

i = 3 , 4 // 從這行可以看出:「應被刪除的元素」3 被其後的「未被刪除的元素」4覆蓋

i = 4 , 3

i = 5 , 4

所以要徹底刪除還應該把後面的殘餘資料刪除掉,這可以通過呼叫容器的成員函式erase()做到。

例 6:

void main()

}vectint.erase( remove( vectint.begin(), vectint.end(), 3 ), vectint.end() );

cout << " after deleted , size = " << vectint.size() << endl;

for ( i = 0; i < vectint.size();; i++ )

}執行結果為:

after deleted , size = 4 // 從這行可以看出,刪除後容器的大小變化了

i = 0 , 0

i = 1 , 1

i = 2 , 2

i = 3 , 4

從結果可以看出,所有值為3的元素確實被刪除了。

對於vector容器存放其他比較複雜的物件,就可以用remove_if()加函式物件(function object)的方法。

如:例7:

#include

#include

#include

#include

#include

#include

using namespace std;

class ctest

void vprint()

private:

string m_strname;

int m_iprice;

// 由於兩個函式物件要訪問ctest類的private成員,所以設為友員。

friend class cstrfunc;

friend class cintfunc;

};// 函式物件,根據string比較

class cstrfunc

bool operator() ( const ctest& left )

};// 函式物件,根據int比較

class cintfunc

bool operator() ( const ctest& left )

};void main( )

for ( i = 0 ; i < vecttest.size(); i++ )

// 刪除所有m_strname = "3"的元素

vecttest.erase( remove_if( vecttest.begin(), vecttest.end(), cstrfunc( "3" ) ),

vecttest.end() );

cout << "delete 3 after : " << endl;

for ( i = 0 ; i < vecttest.size(); i++ )

// 刪除所有m_iprice = 2的元素

vecttest.erase( remove_if( vecttest.begin(), vecttest.end(), cintfunc( 2 ) ),

vecttest.end() );

cout << "delete 2 after : " << endl;

for ( i = 0 ; i < vecttest.size(); i++ )

}手工編寫for迴圈**刪除stl序列式容器中元素的方法,使用stl中通用演算法或容器成員函式刪除元素的方法,兩者之間的比較:

1. 前者**重複。

2. 前者容易出錯,不夠清晰。

3. 效率:

0 1 2 3 2 5 6 7

0 1 3 2 5 6 7

0 1 3 5 6 7

用第一種方法刪除所有值為2的元素

從上圖可以看出,每刪除乙個元素,後面的所有元素都到往前移動一位,導致一次記憶體大搬遷。

0 1 2 3 2 5 6 7

0 1 3 2 5 6 6 7

0 1 3 5 6 7

用第二種方法刪除所有值為2的元素

從上面可以看出,刪除時元素2被後面元素覆蓋,不會到元素移位和記憶體大搬遷,殘餘資料留到末尾一次全部刪除,也不會導致記憶體大搬遷,所以後者的方法要比前者在效率上好很多。

出處:http://www.wangchao.net.cn/bbsdetail_27824.html

STL序列式容器中刪除元素的方法和陷阱二

以上手工編寫 for迴圈 刪除容器中元素的方法也有一些問題,如果判斷條件特別複雜,又有迴圈判斷的話,迴圈中間又有異常處理的話,itvect 的位置就要小心放置了,稍不留意就要出錯。所以手工編寫 刪除容器中元素的方法不太安全,重複,也不夠優雅,要注意的地方很多。對於這種情況,可以考慮使用 stl中通用...

安全刪除STL容器元素

stl容器迭代過程中刪除元素技巧 序列容器的erase方法返回值是指向緊接在被刪除元素之後的元素的有效迭代器,可以根據這個返回值來安全刪除元素。vectorc for vector iterator it c.begin it c.end 關聯容器的 erase 方法沒有返回值,被刪除的迭代器失效,...

STL容器刪除元素的陷阱

今天看scott meyers大師的stl的用法,看到了我前段時間犯的乙個錯誤,發現我寫的 和他提到錯誤 幾乎一模一樣,有關stl容器刪除元素的問題,錯誤的 如下 std vectormfriendlist std vector iterator iter mfriendlist.begin for...