STL中的容器可以分為兩類:一類是按照數(shù)組方式連續(xù)存儲元素的容器,如vector、deque,另一類是按照不連續(xù)的節(jié)點存儲元素的容器,如set、map、list等。
那么這兩類容器刪除元素的時候需要注意一個問題,使用iterator指定刪除某個元素的時候,要注意返回的iterator的值。下面分別舉set、vector的例子來說明。
set刪除元素
假如要刪除set中滿足某個條件的元素,這時候需要遍歷,看代碼:
set<int> s;
s.insert(1);
s.insert(4);
s.insert(2);
s.insert(3);
for (set<int>::iterator it = s.begin(); it != s.end(); it ++)
cout << *it << endl;
for (set<int>::iterator it = s.begin(); it != s.end(); )
{
if (*it % 2 != 0) // 刪除奇數(shù)
s.erase(it++);
else
it ++;
}
大家注意到s.erase(it++)這一句,it++返回是+1之前的it的值,那么此時刪除的正是滿足條件的元素,而it本身又進行了+1,指向了下一個元素,那你可能會問為什么不直接刪除之后再+1呢,如下代碼:
s.erase(it);
it++;
這樣為什么不行呢?因為在erase之前,it其實指向的還是原來的元素,只不過它已經(jīng)不存在set中,那么此時it++,得到的值不是set中的那一個元素,而是不確定的,對這個指針進行訪問,會得到意想不到的結(jié)果,甚至導(dǎo)致程序崩潰。
vector刪除元素
vector內(nèi)部存儲元素是采用數(shù)組方式存儲的,即是連接的,刪除元素可以按照以下方法:
vector<int> ve;
ve.push_back(1);
ve.push_back(3);
ve.push_back(2);
ve.push_back(4);
for (vector<int>::iterator it = ve.begin(); it != ve.end();)
{
if (*it % 2 != 0)
ve.erase(it);
else
it ++;
}
vector跟set不一樣的地方在于,調(diào)用erase之后,it自動指向下一個元素,所以在遍歷刪除的時候需要注意,erase之后不需要再進行it++,否則會跳過了一個元素。