C++ Vector 匯總

C++ vector erase函數

最近使用了順序容器的刪除元素操作,特此記錄下該函數的注意事項。

在C++primer中對c.erase(p) 這樣解釋的:

????????c.erase(p) ?? 刪除迭代器p所指向的元素,返回一個指向被刪元素之后元素的迭代器,若p指向尾元素,則返回尾后迭代器,若p是尾后迭代器,則會產生未定義行為。

??? 這個函數我在使用的過程中發現有那么一點小小的注意事項

如果要想遍歷一個容器,并且刪除某個不符合要求的元素,那么最好使用while而不是使用for

因為

復制代碼
    ????vector<RotatedRect>::iterator  it = m_rect.begin();while((it) != m_rect.end())
        {float diff = abs((*it).size.width - (*(it + 1)).size.width);if( diff > diffmax)
           {if(( it - m_rect.begin())  < (m_rect.size() / 2))   it = m_rect.erase(it); //此時指針已經指向下一個元素,故指針不需要再自增else   it = m_rect.erase(it + 1); }else{it++; //否則指針自增一,while循環可以選擇有條件的讓指針指向下一個元素}}    
復制代碼
復制代碼
    vector<RotatedRect>::iterator  it = m_rect.begin();for( ;(it) != m_rect.end(); it++ )  //如果使用for循環,并且選擇在此處自增一
       {float diff = abs((*it).size.width - (*(it + 1)).size.width);if( diff > diffmax){if(( it - m_rect.begin())  < (m_rect.size() / 2))   it = m_rect.erase(it); //那么將會與這里的自增重復,這樣會造成有元素被跳過else   it = m_rect.erase(it + 1); }}    
復制代碼

我在查閱資料時發現有個博主推薦的寫法是這樣的

此處鏈接http://blog.csdn.net/zhuimengzh/article/details/6841500

復制代碼
void fun(){vector<int> iVec;vector<int>::iterator it;for(int i=0;i<10;i++)iVec.push_back(i);display(iVec);for(it=iVec.begin();it!=iVec.end();++it){if(*it ==4 || *it == 7){it=iVec.erase(it);--it;//這里回退一個       //******該博主推薦在此處自動回退一個,這樣貌似可以用for循環了,但是其實不是的
}}display(iVec);}
復制代碼

如果你刪除的元素是容器的第一個元素,那么回退的行為將是未定義的,切記

?c++ vector begin(),end(),rbegin(),rend()問題

C++ primer (中文版第四版)第273頁

9.3.2 begin和end成員

??????? begin和end操作產生指向“容器內第一個元素”?和 “最后一個元素的下一個位置的迭代器。這兩個迭代器通常用于標記包含容器中所有元素的迭代范圍。

c.begin() 返回一個迭代器,它指向容器c的第一個元素

c.end() 返回一個迭代器,它指向容器c的最后一個元素的下一個位置

c.rbegin() 返回一個逆序迭代器,它指向容器c的最后一個元素

c.rend() 返回一個逆序迭代器,它指向容器c的第一個元素前面的位置

??????? 上述每個操作都有兩個不同的版本:一個是const成員,另一個是非const成員。這些操作返回什么類型取決于容器是否為const。如果容器不是const,則這些操作返回iterator或reverse_iterator類型。如果容器是const,則其返回類型要加上const_前綴,也就是const_iterator和const_reverse_iterator類型。

?

第353頁

11.3.3 反向迭代器

??????? 反向迭代器是一種反向遍歷容器的迭代器。也就是,從最后一個元素到第一個元素遍歷容器。反向迭代器將自增(和自減)的含義反過來了:對于反向迭代器,++ 運算將訪問前一個元素,而 -- 運算則訪問下一個元素。

??????? 回想一下,所有容器都定義了 begin 和 end 成員,分別返回指向容器首元素和尾元素下一位置的迭代器。容器還定義了 rbegin 和 rend 成員,分別返回指向容器尾元素和首元素前一位置的反向迭代器。與普通迭代器一樣,反向迭代器也有常量(const)和非常量(nonconst)類型。圖 11.1 使用一個假設名為 vec 的 vector 類型對象闡明了這四種迭代器之間的關系。

圖?1 比較 begin/end 和 rbegin/rend 迭代器

??????假設有一個 vector 容器對象,存儲 0-9 這 10 個以升序排列的數字:

[html]?view plain?copy
  1. vector<int>?vec;??
  2. for?(vector<int>::size_type?i?=?0;?i?!=?10;?++i)??
  3. ??????vec.push_back(i);?//?elements?are?0,1,2,...9??


?

下面的 for 循環將以逆序輸出這些元素:

[html]?view plain?copy
  1. //?reverse?iterator?of?vector?from?back?to?front??
  2. vector<int>::reverse_iterator?r_iter;??
  3. for?(r_iter?=?vec.rbegin();?//?binds?r_iter?to?last?element??
  4. ??????r_iter?!=?vec.rend();?//?rend?refers?1?before?1st?element??
  5. ??????++r_iter)?//?decrements?iterator?one?element??
  6. ????cout?<<?*r_iter?<<?endl;?//?prints?9,8,7,...0 ?

????? 雖然顛倒自增和自減這兩個操作符的意義似乎容易使人迷惑,但是它讓程序員可以透明地向前或向后處理容器。

例如,為了以降序排列 vector,只需向 sort傳遞一對反向迭代器:

[html]?view plain?copy
  1. //?sorts?vec?in?"normal"?order??
  2. sort(vec.begin(),?vec.end());??
  3. //?sorts?in?reverse:?puts?smallest?element?at?the?end?of?vec??
  4. sort(vec.rbegin(),?vec.rend());??


????? 1.反向迭代器需要使用自減操作符

????? 從一個既支持 -- 也支持 ++ 的迭代器就可以定義反向迭代器,這不用感到吃驚。畢竟,反向迭代器的目的是移動迭代器反向遍歷序列。標準容器上的迭代器既支持自增運算,也支持自減運算。但是,流迭代器卻不然,由于不能反向遍歷流,因此流迭代器不能創建反向迭代器。

流迭代器:https://www.cnblogs.com/ll-10/p/5461374.html 【流迭代器是一種迭代器適配器。istream_iterator用于讀取輸入流,ostream_iterator用于寫輸出流。這些迭代器將它們所對應的流視為特定類型的元素序列。使用流迭代器時,可以用泛型算法從流對象中讀數據或將數據寫入到流對象中。

????? 2.反向迭代器與其他迭代器之間的關系
????? 假設有一個名為 line 的 string 對象,存儲以逗號分隔的單詞列表。我們希望輸出 line 中的第一個單詞。使用 find 可很簡單地實現這個任務:
[html]?view plain?copy
  1. //?find?first?element?in?a?comma-separated?list??
  2. string::iterator?comma?=?find(line.begin(),?line.end(),?',');??
  3. cout?<<?string(line.begin(),?comma)?<<?endl; ?

如果在 line 中有一個逗號,則 comma 指向這個逗號;否則,comma 的值為 line.end()。在輸出 string 對象中從 line.begin() 到 comma 的內容時,從頭開始輸出字符直到遇到逗號為止。如果該 string 對象中沒有逗號,則輸出整個 string 字符串。
????? 如果要輸出列表中最后一個單詞,可使用反向迭代器:

[html]?view plain?copy
  1. //?find?last?element?in?a?comma-separated?list??
  2. string::reverse_iterator?rcomma?=?find(line.rbegin(),?line.rend(),?','); ?

因為此時傳遞的是 rbegin() 和 rend(),這個函數調用從 line 的最后一個字符開始往回搜索。當 find 完成時,如果列表中有逗號,那么 rcomma 指向其最后一個逗號,即指向反向搜索找到的第一個逗號。如果沒有逗號,則 rcomma 的值為 line.rend()。
????? 在嘗試輸出所找到的單詞時,有趣的事情發生了。直接嘗試:

[html]?view plain?copy
  1. //?wrong:?will?generate?the?word?in?reverse?order??
  2. cout?<<?string(line.rbegin(),?rcomma)?<<?endl; ?

會產生假的輸出。例如,如果輸入是:
????? FIRST,MIDDLE,LAST
則將輸出 TSAL!

????? 圖 2 闡明了這個問題:使用反向迭代器時,以逆序從后向前處理 string對象。為了得到正確的輸出,必須將反向迭代器 line.rbegin() 和 rcomma 轉換為從前向后移動的普通迭代器。其實沒必要轉換 line.rbegin(),因為我們知道轉換的結果必定是 line.end()。只需調用所有反向迭代器類型都提供的成員
函數 base 轉換 rcomma 即可:

[html]?view plain?copy
  1. //?ok:?get?a?forward?iterator?and?read?to?end?of?line??
  2. ?cout?<<?string(rcomma.base(),?line.end())?<<?endl; ?

假設還是前面給出的輸入,該語句將如愿輸出 LAST。

圖 2. 反向迭代器與普通迭代器之間的區別

????? 圖 2 顯示的對象直觀地解釋了普通迭代器與反向迭代器之間的關系。例如,正如 line_rbegin() 和 line.end() 一樣,rcomma 和 rcomma.base() 也指向不同的元素。為了確保正向和反向處理元素的范圍相同,這些區別必要的。從技術上來說,設計普通迭代器與反向迭代器之間的關系是為了適應左閉合范圍(第 9.2.1 節)這個性質的,所以,[line.rbegin(), rcomma) 和[rcomma.base(), line.end()) 標記的是 line 中的相同元素。

? ? ? 反向迭代器用于表示范圍,而所表示的范圍是不對稱的,這個事實可推導出一個重要的結論:

使用普通的迭代器對反向迭代器進行初始化或賦值時,所得到的迭代器并不是指向原迭代器所指向的元素。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/458411.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458411.shtml
英文地址,請注明出處:http://en.pswp.cn/news/458411.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vNext之旅(2):net451、dotnet5.4、dnx451、dnxcore50都是什么鬼

繼上次”vNext之旅&#xff08;1&#xff09;&#xff1a;從概念和基礎開始”之后再次學習vNext重新遇到了弄不懂的事情&#xff0c;花了一些時間學習&#xff0c;今天來分享一下&#xff0c;為后人節省些時間。起因 在用vNext造輪子——框架的時候引入“Microsoft.Dnx.Runtime…

C++中模板使用詳解

轉自&#xff1a;http://www.360doc.com/content/09/0403/17/799_3011262.shtml 1. 模板的概念。 我們已經學過重載(Overloading)&#xff0c;對重載函數而言,C的檢查機制能通過函數參數的不同及所屬類的不同。正確的調用重載函數。例如&#xff0c;為求兩個數的最大值&#xf…

騰訊2016春招安全崗筆試題解析

騰訊2016春招安全崗筆試題解析 昨天&#xff08;4月2日&#xff09;晚上7:00到9:00做了騰訊春招安全崗的筆試題。下面解析一下&#xff1a; 題目解析 1 在生成隨機數前用當前時間設置隨機數種子應該是安全的。如果程序用固定的數產生隨機數&#xff0c;其結果也是固定的。如果用…

網絡請求數據解析時,判斷數據是否為空

//判斷是否為空 (BOOL)IsStringEmptyOrNull:(NSString *)str { if (!str) { // null object return true; }else if (str nil){ return true; }else { if ([str isKindOfClass:[NSNull class]]) { return true; …

VS項目屬性的一些配置項的總結(持續增加。。。)

首先&#xff0c;解決方案和項目文件夾包含關系(c項目)&#xff1a; VS解決方案和各個項目文件夾以及解決方案和各個項目對應的配置文件包含關系&#xff1a;假設新建一個項目ssyy&#xff0c;解決方案起名fangan&#xff0c;注意解決方案包括項目&#xff0c;此時生成的最外層…

shell編程中date用法(轉)

原文地址:http://blog.sina.com.cn/s/blog_61c006ea0100mgxe.html 1、date --help %% 輸出%符號 a literal % %a 當前域的星期縮寫 locale’s abbreviated weekday name (Sun..Sat) %A 當前域的星期全寫 locale’s full weekday name, variable length (Sunday..Saturday) %b 當…

linux下搭建FTP服務器

LINUX FTP簡單配置 FTP配置1、#vi /etc/vsftp/vsftpd.conf #主要配置幾個關鍵的就可以 anonymous_enableNO #拒絕匿名訪問 chroot_local_userYES #鎖定用戶目錄&#xff0c…

微信正則表達式 iOS

#pragma mark - 微信號的正則表達式 微信賬號僅支持6-20個字母、數字、下劃線或減號&#xff0c;以字母開頭 (BOOL)isWxNumber:(NSString *)WXNum{ NSString *passWordRegex "^[a-zA-Z][a-zA-Z0-9_-]{5,19}$"; NSPredicate *passWordPredicate [NSPredica…

子元素增加margin-top會增加給父元素的問題

假設我們有如下代碼 <div id"father" style"height:400px;width:400px;background:#e4393c;">     <div id"child" style"background:green;height:100px;width:100px;margin-top:40px;"></div>   </div&g…

Python 關鍵字

from&#xff1a;https://blog.csdn.net/liang19890820/article/details/68488392簡述 關鍵字是預先保留的標識符&#xff0c;每個關鍵字都有特殊的含義。編程語言眾多&#xff0c;但每種語言都有相應的關鍵字&#xff0c;Python 也不例外&#xff0c;它自帶了一個 keyword 模塊…

Zend Studio使用教程之升級Zend Studio(1/3)

2019獨角獸企業重金招聘Python工程師標準>>> Zend Studio是新一代的專業級智能PHP IDE&#xff0c;它旨在幫助開發人員提高工作效率&#xff0c;創造出高品質的PHP應用程序&#xff01;它包含了PHP開發所必須的部件&#xff0c;通過一整套的編輯、調試、分析、優化和…

身份證正則表達式

#pragma mark - 身份證的正則表達式 (BOOL)checkUserID:(NSString *)userID { //長度不為18的都排除掉 if (userID.length!18) { return NO; } //校驗格式 NSString *regex2 "^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d…

java中可重入鎖的學習總結

2019獨角獸企業重金招聘Python工程師標準>>> 經常看到網上的人說&#xff0c;可重入鎖一詞&#xff0c;但是總是沒怎么了解&#xff0c;到底什么是可重入鎖&#xff0c;一直是一個模糊的概念&#xff0c;下面來大致總結一下。 可重入鎖&#xff1a;指的是同一個線程…

Oracle DB優化

http://www.jb51.net/article/77876.htm http://www.jb51.net/article/56881.htm http://danni505.blog.51cto.com/15547/1163711/ http://blog.csdn.net/giianhui/article/details/8172786轉載于:https://www.cnblogs.com/diyunpeng/p/5132392.html

設置View單個圓角

#pragma mark - 設置View單個圓角 (void)addCornerWithView:(UIView *)aView type:(UIRectCorner)aCorners size:(CGSize)aSize { // 根據矩形畫帶圓角的曲線 UIBezierPath *maskPath [UIBezierPath bezierPathWithRoundedRect:aView.bounds byRoundingCorners:aCorn…

Python 數據類型

簡述Python 中的每個值都有一個數據類型。在 Python 編程中&#xff0c;一切&#xff08;萬物&#xff09;皆對象&#xff0c;數據類型實際上是類&#xff0c;變量是這些類的實例&#xff08;對象&#xff09;。簡述數據類型Number數字String字符串List列表Tuple元組Set集合Dic…

基于用戶投票的排名算法(一):Delicious和Hacker News

互聯網的出現&#xff0c;意味著"信息大爆炸"。 用戶擔心的&#xff0c;不再是信息太少&#xff0c;而是信息太多。如何從大量信息之中&#xff0c;快速有效地找出最重要的內容&#xff0c;成了互聯網的一大核心問題。 各種各樣的排名算法&#xff0c;是目前過濾信息…

iOS 修改工程名

一兩個月之前&#xff0c;公司要求將現在的項目&#xff08;發貨端和接單端在一個項目里&#xff09;&#xff0c;拆分成兩個項目分別是接單端項目和發貨端項目&#xff0c;原有的項目還不能下架。這種情況就要考慮蘋果審核查代碼的重復率的問題了。老板的要求除了改變項目的主…

Windows 下 Python 環境搭建

簡述Python 是跨平臺的&#xff0c;可以運行在 Windows、Mac OS X 和各種 Linux/Unix 系統上。在學習 Python 之前&#xff0c;首先要搭建 Python 環境。完成后&#xff0c;會得到 Python 解釋器&#xff08;負責運行 Python 程序的&#xff09;&#xff0c;一個命令行交互環境…

面試中關于Java你所需知道的的一切

本篇文章會對面試中常遇到的Java技術點進行全面深入的總結&#xff0c;幫助我們在面試中更加得心應手&#xff0c;不參加面試的同學也能夠借此機會梳理一下自己的知識體系&#xff0c;進行查漏補缺。 1. Java中的原始數據類型都有哪些&#xff0c;它們的大小及對應的封裝類是什…