void Remove1(vector<int> &vec, int num)
{
vector<int>::iterator iter;
for (iter=vec.begin(); iter!=vec.end(); ++iter)
{
if (*iter == num)
{
vec.erase(iter);
}
}
}
void Remove2(list<int> &lst, int num)
{
list<int>::iterator iter;
for (iter=lst.begin(); iter!=lst.end(); ++iter)
{
if (*iter == num)
{
lst.erase(iter);
}
}
}
int main(void)
{
int arr[] = {1, 3, 5, 5, 7, 9};
int num = sizeof(arr) / sizeof(arr[0]);
vector<int> vec(arr, arr+num);
list<int> lst(arr, arr+num);
Remove1(vec, 5);
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
//Remove2(lst, 5);
//copy(lst.begin(), lst.end(), ostream_iterator<int>(cout, " "));
return 0;
}
它們編譯都沒什么問題,但是運行有問題:
先注釋Remove2這兩行, 編譯運行, 得到結果是:1 3 5 7 9
顯然結果是錯誤的,因為還有個5沒刪掉。造成這樣結果的原因是vec.erase之后iter會自加,執行下次for循環時++iter,這樣就跳過了與所刪除元素相鄰的元素了。
再來看下Remove2, 注釋掉Remove1, 刪除Remove2的注釋。
運行出錯,vs2005 Expression:list iterator not incrementable,說明list迭代器++iter有問題。
list是一個雙向鏈表,在erase(iter)之后iter失效了,printf("0x%x", iter);得到結果為0,只有erase的返回值才能指向下一個元素。
Remove1的正確用法是:vec.erase(remove(vec.begin(), vec.end(), 5), vec.end());
Remove2的正確用法是:lst.remove(5);
下面是另一種正確寫法:
// 刪除某一類元素, 比如:偶數
void Remove3(std::set<int>& sets)
{
std::set<int>::iterator iter = sets.begin();
while (iter != sets.end())
{
if (0 == (*iter)%2)
{
// 注意這里不能寫成++iter,后面說明原因
sets.erase(iter++);
}
else
{
++iter;
}
}
}
void Remove4(std::map<int, int>& maps)
{
std::map<int, int>::iterator iter = maps.begin();
while (iter != maps.end())
{
if (0 == (iter->first)%2)
{
maps.erase(iter++);
}
else
{
++iter;
}
}
}
新聞熱點
疑難解答
圖片精選