日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ Vector 汇总

發布時間:2023/12/20 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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
  • vector<int>?vec;??
  • for?(vector<int>::size_type?i?=?0;?i?!=?10;?++i)??
  • ??????vec.push_back(i);?//?elements?are?0,1,2,...9??

  • ?

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

    [html]?view plain?copy
  • //?reverse?iterator?of?vector?from?back?to?front??
  • vector<int>::reverse_iterator?r_iter;??
  • for?(r_iter?=?vec.rbegin();?//?binds?r_iter?to?last?element??
  • ??????r_iter?!=?vec.rend();?//?rend?refers?1?before?1st?element??
  • ??????++r_iter)?//?decrements?iterator?one?element??
  • ????cout?<<?*r_iter?<<?endl;?//?prints?9,8,7,...0 ?
  • ????? 雖然顛倒自增和自減這兩個操作符的意義似乎容易使人迷惑,但是它讓程序員可以透明地向前或向后處理容器。

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

    [html]?view plain?copy
  • //?sorts?vec?in?"normal"?order??
  • sort(vec.begin(),?vec.end());??
  • //?sorts?in?reverse:?puts?smallest?element?at?the?end?of?vec??
  • 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
  • //?find?first?element?in?a?comma-separated?list??
  • string::iterator?comma?=?find(line.begin(),?line.end(),?',');??
  • cout?<<?string(line.begin(),?comma)?<<?endl; ?
  • 如果在 line 中有一個逗號,則 comma 指向這個逗號;否則,comma 的值為 line.end()。在輸出 string 對象中從 line.begin() 到 comma 的內容時,從頭開始輸出字符直到遇到逗號為止。如果該 string 對象中沒有逗號,則輸出整個 string 字符串。
    ????? 如果要輸出列表中最后一個單詞,可使用反向迭代器:

    [html]?view plain?copy
  • //?find?last?element?in?a?comma-separated?list??
  • string::reverse_iterator?rcomma?=?find(line.rbegin(),?line.rend(),?','); ?
  • 因為此時傳遞的是 rbegin() 和 rend(),這個函數調用從 line 的最后一個字符開始往回搜索。當 find 完成時,如果列表中有逗號,那么 rcomma 指向其最后一個逗號,即指向反向搜索找到的第一個逗號。如果沒有逗號,則 rcomma 的值為 line.rend()。
    ????? 在嘗試輸出所找到的單詞時,有趣的事情發生了。直接嘗試:

    [html]?view plain?copy
  • //?wrong:?will?generate?the?word?in?reverse?order??
  • 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
  • //?ok:?get?a?forward?iterator?and?read?to?end?of?line??
  • ?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 中的相同元素。

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

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


    總結

    以上是生活随笔為你收集整理的C++ Vector 汇总的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。