1. 程式人生 > >關於STL的list,vector等用迭代器iterator,用erase刪除元素出現的問題。

關於STL的list,vector等用迭代器iterator,用erase刪除元素出現的問題。

做個測試,隨便搞個類,標頭檔案加入

#include <vector>
#include <list>
using namespace std;

typedef std::vector<CString> CStringVector;

然後在一個可執行到的方法中加入如下程式碼:

CStringVector vctCString;
vctCString.push_back(_T("1111"));
vctCString.push_back(_T("2222"));
vctCString.push_back(_T("3333"));
vctCString.push_back(_T("4444"));
vctCString.push_back(_T("5555"));


CStringVector::iterator it = vctCString.begin();
for (; it != vctCString.end(); it++)
{
    CString strTemp = *it;
    if (strTemp == _T("1111"))
    {
        vctCString.erase(it);
    }
}

很明顯,當erase那個it後,再執行it++就會失敗,這是最常見的問題,erase之後會導致it失效,怎麼解決呢?

erase的返回值是下一個元素的位置,讓這個值重新付給it就行了。但是粗心的人會這麼寫:

CStringVector vctCString;
vctCString.push_back(_T("1111"));
vctCString.push_back(_T("1111"));
vctCString.push_back(_T("3333"));
vctCString.push_back(_T("4444"));
vctCString.push_back(_T("5555"));


CStringVector::iterator it = vctCString.begin();
for (; it != vctCString.end(); it++)
{
    CString strTemp = *it;
    if (strTemp == _T("1111"))
    {
        CStringVector::iterator itTemp = vctCString.erase(it);
        it = itTemp;
    }
}
這麼寫對嗎?也不對,但不會崩潰,也就是解決了前面的問題,但是帶來了新的問題,這樣寫的話會導致這個for迴圈少迴圈一次,也就少判斷了一次,哪一次呢?就是if成立後的下一個元素,沒有判斷到,原因就不用說了吧。

最正確的寫法是:

CStringVector vctCString;
vctCString.push_back(_T("1111"));
vctCString.push_back(_T("1111"));
vctCString.push_back(_T("3333"));
vctCString.push_back(_T("4444"));
vctCString.push_back(_T("5555"));


CStringVector::iterator it = vctCString.begin();
for (; it != vctCString.end(); )
{
    CString strTemp = *it;
    if (strTemp == _T("1111"))
    {
        CStringVector::iterator itTemp = vctCString.erase(it);
       it = itTemp;
    }
    else
    {
        it++;
    }
}

什麼意思?for小括號裡的it++不寫了,放到裡面來,這樣當if有效的時候,其實已經是it++過了,所以這種情況不需要小括號內再++了,再++就加多了,當if無效的時候正常執行else的it++。明白了不?不明白給我發郵件吧。[email protected]

相關推薦

關於STL的listvectoriteratorerase刪除元素出現的問題

做個測試,隨便搞個類,標頭檔案加入 #include <vector>#include <list>using namespace std; typedef std::vector<CString> CStringVector; 然後在

java-Collection集合、List集合、Vector集合和Iterator、ListIterator的使用

1、物件陣列的概述和使用  * A:案例演示     * 需求:我有5個學生,請把這個5個學生的資訊儲存到陣列中,並遍歷陣列,獲取得到每一個學生資訊。    *     Student[] arr = new Student[5]; //儲存學生物件     arr[0] = new Student("張三

標準庫vector型別和iterator型別

對C++ Primer 中文版第4版  第三章標準庫型別中的vector型別和迭代器iterator型別做一個總結。 vector稱為容器,是同一種類型的物件的集合。一個容器中的所有物件都必須是同一種類型。 1.使用vector之前,必須包含相應的標頭檔案。宣告如下:  

C++11 你真的會(iterator)麼?

C++ STL提供了豐富的標準容器(Container)物件(vector,array,queue,list,set,unordered_map/set…),讓我們可以根據需求選擇不同的容器管理各種型別的資料。說到使用容器,不用迭代器(iterator)是不可能

有什麼意義何在?

迭代器就是把不同的資料結構 "相同功能 "的函式裝到一個名字相同的函式裡,這樣的話你在寫演算法的時候就可以不管你要操作的資料結構的邏輯結構了。 比如不管是連結串列,陣列還是別的什麼,統一都用迭代器進行訪問的話可能都是   Next()表示下一個元素   Pre()表示上一個元素等等 。 其實意思就是,

還在處理集合嗎?試試Stream真香

## 前言 上一篇部落格[一文帶你深入瞭解 Lambda 表示式和方法引用](https://www.cnblogs.com/keatsCoder/p/12839050.html)我給大家介紹了 Java8 函式式特性中的 Lambda,這篇文章我將繼續討論 stream 流的用法 宣告:本文首發於部落格

vector容器、和空間配置三個類方法的實現

C++的STL庫有一個容器叫vector,這個容器底層的資料結構是一個記憶體可以自動增長的陣列,每次當陣列儲存滿了以後,記憶體可以自動增加兩倍,請完成vector容器、迭代器和空間配置器三個類方法的實現。 #include<iostream> using namespace std; //容器預

Scala 陣列(Array)列表(List)元組(Tuple)集(Set)對映(Map)(Iterator)

1. 陣列(Array) 陣列是程式設計中經常用到的資料結構,一般包括定長陣列和變長陣列。本教程旨在快速掌握最基礎和常用的知識,因此,只介紹定長陣列。 定長陣列,就是長度不變的陣列,在Scala中使用Array進行宣告,如下: val intValue

HashSet建立及遍歷

輸入三個字串,並看裡邊是否含有“Kobe”。 import java.util.Scanner; import java.util.HashSet; import java.util.Iterator

實現斐波那契數列

可以直接作用於for迴圈的物件統稱為可迭代物件:Iterable 可以被next()函式呼叫並不斷返回下一個值的物件稱為迭代器:Iterator 參考:Python學習筆記 - 迭代器Iterator 用迭代器實現斐波那契數列 Python3環境下可實現迭代: class

模版方法模式模式組合模式狀態模式代理模式

1.模版方法模式:在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中,模版方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟,還可以提供hook()讓子類決定是否執行某些步驟。比如sort中的Comparable介面。 2.迭代器模式就是集合的迭代器 3.組合模式

容器vectoriterator的學習使用

vector、algorithm、deque、functional、iterrator、list、map、memory、numeric、queue、set、stack、utility vector的宣告: vector<type> vec;size();r

vector中利用刪除滿足一定條件的元素或者值

#include "stdafx.h" #include <vector> #include <time.h> #include <assert.h> #inclu

C++ vector中的失效問題

vector中的迭代器失效問題 在使用vector的成員函式時,有兩個成員函式內部會出!](https://img-blog.csdnimg.cn/20181124093029161.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5na

實戰c++中的vector系列--將轉換為索引

stl的迭代器很方便 用於各種演算法。 但是一想到vector,我們總是把他當做陣列,總喜歡使用下標索引,而不是迭代器。 這裡有個問題就是如何把迭代器轉換為索引: #include <vector> typedef std::vector

c++學習-為什麼要

本文記錄我對迭代器的一點理解。先列出參考的文章[LevelDB原始碼分析–使用Iterator簡化程式碼設計]。我對參考文章的內容自己做了實現,我講的不清楚的地方可以直接參考原文。 為什麼要設計迭代器這個東西 用迭代器可以很大程度上隔離容器底層實現

C++容器vectoriterator

vector是同一種物件的集合,每個物件都有一個對應的整數索引值。和string物件一樣,標準庫將負責管理與儲存元素相關的類存。引入標頭檔案#include<vector>1.vector物件的定義和初始化[cpp]vector<T> v1      

vector中使用注意事項

1.使用iter++;和++iter;兩種方式遍歷的次數是相同的,但在STL中效率不同。前++返回引用,後++返回一個臨時物件,因為iterator是類模板,使用 iter++這種形式要返回一個無用的臨時物件,而it++是函式過載,所以編譯器無法對其進行優化,所以每遍歷一個

vector物件的定義和初始化以及vectoriterator

向vector新增元素 push_back()操作接受一個元素值,並將它作為一個新的元素新增到vector物件的後面,也就是“插入(push)”到vector物件的“後面(back)”: vector迭代器 除了使用下標來訪問vector物件的元素外,標準庫還提供了另一種檢測元素的方法:使用迭代器(itera

js 模式優雅的處理遞迴問題

開發十年,就只剩下這套架構體系了! >>>