插入迭代器、流迭代器、反向迭代器、移動迭代器

文章目錄

  • 前言
  • 插入迭代器
    • inserter
    • front_inserter
    • back_inserter
  • iostream迭代器
    • istream_iterator 讀取輸入流
      • istream_iterator允許使用懶惰求值
    • ostream_iterator操作
  • 反向迭代器
    • reverse_iterator的base成員函數


前言

除了為每個容器定義的迭代器之外,標準庫在頭文件iterator中還定義了額外幾種迭代器。這些迭代器包括以下幾種。

  • 插入迭代器(insert iterator):這些迭代器被綁定到一個容器上,可用來向容器插入元素。
  • 流迭代器(stream iterator):這些迭代器被綁定到輸入或輸出流上,可用來遍歷所關聯的IO流。
  • 反向迭代器(reverse iterator):這些迭代器向后而不是向前移動。除了forward_list之外的標準庫容器都有反向迭代器。
  • 移動迭代器(move iterator):這些專用的迭代器不是拷貝其中的元素,而是移動它們。


插入迭代器

在這里插入圖片描述
插入器有三種類型,差異在于元素插入的位置:

  • back_inserter創建一個使用push_back的迭代器。
  • front_inserter創建一個使用push_front的迭代器。
  • inserter創建一個使用insert的迭代器。此函數接受第二個參數,這個參數必須是一個指向給定容器的迭代器。元素將被插入到給定迭代器所表示的元素之前。

inserter

當調用inserter(c,iter)時,我們得到一個迭代器,接下來使用它時,會將元素插入到iter原來所指向的元素之前的位置。即,如果it是由inserter生成的迭代器,則下面這樣的賦值語句:

*it = val;

等價于:

it = c.insert(it, val); // it指向新加入的元素val
++it; // 遞增it使其指向原來的元素

front_inserter

一直向首元素位置添加元素,添加后指向新的首元素。

以以下實例區分inserter和front_inserter的區別:
在這里插入圖片描述
在這里插入圖片描述


back_inserter

向容器尾部不斷添加元素。

以unique_copy函數為實例來觀察back_inserter的作用:

值得注意的是,與unique一樣,unique_copy也要求在源容器中重復元素是相鄰存放的,因此容器如果無序且重復元素未相鄰存放,unique_copy會失敗,穩妥起見應該先對vector排序。

  vector<int> vi = {2, 6, 7, 13, 15, 20, 22, 23, 25, 30};list<int> li;ostream& os(cout);int n = 10;while(n--){vi.push_back(n);}sort(vi.begin(), vi.end());for(auto i : vi){os << i << ends;}os << endl;unique_copy(vi.begin(), vi.end(), back_inserter(li));for(auto i : li){os << i << ends;}os << endl;

輸出結果:
在這里插入圖片描述



iostream迭代器

雖然iostream類型不是容器,但是標準庫定義了可以用于這些IO類型對象的迭代器。


istream_iterator 讀取輸入流

在這里插入圖片描述
流迭代器不支持遞減運算,因為不可能在一個流中反向移動。

istream_iterator使用>>來讀取流。因此,istream_iterator要讀取的類型必須定義了輸入運算符。

  • 當創建一個istream_iterator時,可以將它綁定到一個流
  • 默認初始化相當于創建一個可以當作尾后值使用的迭代器。

在這里插入圖片描述
用istream_iterator從標準輸入讀取數據,存入一個vector:
在這里插入圖片描述
istream_iterator可以用來構建容器:

istream_iterator<int> in_iter(cin);
istream_iterator<int> eof;
vector<int> vec(in_iter, eof);

本例中我們用一對表示元素范圍的迭代器來構造vec。這兩個迭代器是istream_iterator,這意味著元素范圍是通過從關聯的流中讀取數據獲得的。這個構造函數從cin中讀取數據,直至遇到文件尾或者遇到一個不是int的數據為止。從流中讀取的數據被用來構造vec。


istream_iterator允許使用懶惰求值

當我們將一個istream_iterator綁定到一個流時,標準庫并不保證迭代器立即從流讀取數據。 具體實現時可以推遲從流中讀取數據的時機——直到我們使用迭代器時才真正讀取。標準庫中的實現所保證的是,在我們第一次解引用迭代器之前,從流中讀取數據的操作已經完成了。 對于大多數程序來說,立即讀取還是推遲讀取沒什么差別。但是,如果我們創建了一個istream_iterator,沒有使用就銷毀了,或者我們正在從兩個不同的對象同步讀取同一個流,那么何時讀取可能就很重要了。



ostream_iterator操作

可以對任何具有輸出運算符(<<運算符)的類型定義ostream_iterator。

當創建一個ostream_iterator時,我們可以提供(可選的)第二參數,它是一個字符串,在輸出每個元素后都會打印此字符串。此字符串必須是一個C風格字符串(即,一個字符串字面常量或者一個指向以空字符結尾的字符數組的指針)。

與iostream_iterator不同的是:必須將ostream_iterator綁定到一個指定的流,不允許空的或表示尾后位置的ostream_iterator。
在這里插入圖片描述
可以用ostream_iterator來輸出值的序列:
在這里插入圖片描述
此程序將vec中的每個元素寫到cout,每個元素后加一個空格。每次向out_iter賦值時,寫操作就會被提交。

值得注意的是,當我們向out_iter賦值時,可以忽略解引用和遞增運算。即,循環可以重寫成下面的樣子:

istream_iterator<int> in_iter(cin);
istream_iterator<int> eof;
vector<int> vec(in_iter, eof);
ostream_iterator<int> out_iter(cout, " ");
for(auto i : vec){out_iter = i;
}
cout << endl;

運算符*和++實際上對ostream_iterator對象不做任何事情,因此忽略它們對我們的程序沒有任何影響。 但是,推薦第一種形式。在這種寫法中,流迭代器的使用與其他迭代器的使用保持一致。如果想將此循環改為操作其他迭代器類型,修改起來非常容易。而且,對于讀者來說,此循環的行為也更為清晰。

可以通過調用copy來打印vec中的元素,這比編寫循環更為簡單:

copy(vec.begin(), vec.end(), out_iter);
cout << endl;

可以用unique_copy代替copy只打印不重復元素:
在這里插入圖片描述



反向迭代器

反向迭代器就是在容器中從尾元素向首元素反向移動的迭代器。對于反向迭代器,遞增(以及遞減)操作的含義會顛倒過來。遞增一個反向迭代器(++it)會移動到前一個元素;遞減一個迭代器(- -it)會移動到下一個元素。

在這里插入圖片描述
反向迭代器逆序打印vector<int>中的元素:
在這里插入圖片描述
對照普通迭代器可以看出,rbegin指向尾元素,rend指向首元素前,遞增和遞減操作的含義會顛倒過來:反向迭代器的遞增操作會移動到前一個元素。

反向迭代器也有十分方便的時候,比如不加額外參數就可以使得元素降序排列:
在這里插入圖片描述

reverse_iterator的base成員函數

base成員函數用來將反向迭代器轉換成其對應的普通迭代器(當然反過來也是可以的,普通迭代器轉換成對應的反向迭代器):
在這里插入圖片描述

圖中的對象顯示了普通迭代器與反向迭代器之間的關系。例如,rcomma和rcomma.base()指向不同的元素,line.crbegin和line.cend()也是如此。這些不同保證了元素范圍無論是正向處理還是反向處理都是相同的。

從技術上講,普通迭代器與反向迭代器的關系反映了左閉合區間的特性。關鍵點在于[line.crbegin(),rcomma)[rcomma.base(),line.cend())指向line中相同的元素范圍。為了實現這一點,rcomma和rcomma.base()必須生成相鄰位置而不是相同位置,crbegin()和cend()也是如此。


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

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

相關文章

泛型算法(lambda表達式、function類模板、bind函數適配器、迭代器類別、鏈表數據結構獨有的算法)

文章目錄概念find()函數迭代器令算法不依賴于容器但算法依賴于元素類型的操作算法永遠不會執行容器的操作只讀算法accumulate()函數從兩個序列中讀取元素&#xff08;equal函數為例&#xff09;迭代器作為參數形成兩個序列equal()寫容器元素的算法概念fill()fill_n()插入迭代器…

jsp,div 限制字數,超出部分用省略號代替

1.我是用struts2標簽做的&#xff1a;如下&#xff1a; <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <% taglib prefix"s" uri"/struts-tags"%> <%String path request.getContext…

C++之關聯容器

文章目錄概述及類型mapsetpair類型概念初始化默認初始化提供初始化器允許的操作可以創建一個pair類的函數可以作為容器的類型關聯容器迭代器概念map的迭代器set的迭代器是const的初始化map and setmultimap and multiset關聯容器的操作額外的類型別名關聯容器和算法刪除元素添加…

動態內存、智能指針(shared_ptr、unique_ptr、weak_ptr)、動態數組

文章目錄三種對象的分類三種內存的區別動態內存概念智能指針允許的操作智能指針的使用規范new概念內存耗盡/定位new初始化默認初始化直接初始化值初始化delete概念手動釋放動態對象空懸指針shared_ptr類格式獨有的操作make_shared函數shared_ptr的計數器通過new用普通指針初始化…

動態數組的簡單應用

文章目錄連接兩個字符串字面常量題目注意代碼輸出結果處理輸入的變長字符串題目注意代碼連接兩個字符串字面常量 題目 連接兩個字符串字面常量&#xff0c;將結果保存在一個動態分配的char數組中。重寫&#xff0c;連接兩個標準庫string對象。 注意 使用頭文件cstring的str…

二分查找算法實現

文章目錄思路代碼以二分區間作為while判定條件以給定值作為while判定條件主函數思路 while判定條件的選擇&#xff0c;注意最外層的return的內容就好。下面提供了兩個代碼版本。計算 mid 時需要防止溢出&#xff08;對應類型【如本例中的int】可能存不下&#xff09;&#xff…

Windows下Spring3.x計劃任務實現定時備份MySql數據庫

今天在空閑之余查了一下關于MySql數據庫備份的方案&#xff0c;最后結合自己的項目情況寫了一個關于Spring計劃任務的例子&#xff0c;目前我這個版本是在Windwos下測試成功&#xff0c;希望對大家有所幫助&#xff0c;不足之處還請大家多多包含&#xff0c;有什么建議盡管提出…

根據中序、前序遍歷重建二叉樹

文章目錄題目遞歸思路細節易錯代碼復雜度分析迭代思路細節易錯代碼復雜度分析題目 輸入某二叉樹的前序遍歷和中序遍歷的結果&#xff0c;請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重復的數字。 例如&#xff0c;給出 前序遍歷 preorder [3,9,20,15,7] 中…

深搜+剪枝

文章目錄題目思路注意代碼復雜度分析題目 給定一個 m x n 二維字符網格 board 和一個字符串單詞 word 。如果 word 存在于網格中&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false 。 單詞必須按照字母順序&#xff0c;通過相鄰的單元格內的字母構成&#xff0c…

搜索+回溯問題(DFS\BFS詳解)

文章目錄題目思路DFS思路代碼復雜度分析BFS思路代碼復雜度分析題目 地上有一個m行n列的方格&#xff0c;從坐標 [0,0] 到坐標 [m-1,n-1] 。一個機器人從坐標 [0, 0] 的格子開始移動&#xff0c;它每次可以向左、右、上、下移動一格&#xff08;不能移動到方格外&#xff09;&am…

剪繩子(動規、數論、貪心)

文章目錄題目數論思路代碼復雜度分析動規一思路代碼動規二思路代碼對最終結果取模1e97思路代碼題目 給你一根長度為 n 的繩子&#xff0c;請把繩子剪成整數長度的 m 段&#xff08;m、n都是整數&#xff0c;n>1并且m>1&#xff09;&#xff0c;每段繩子的長度記為 k[0],…

快速冪實現pow函數(從二分和二進制兩種角度理解快速冪)

文章目錄迭代實現快速冪思路int的取值范圍快速冪從二進制的角度來理解從二分法的角度來理解代碼復雜度分析進階——超級次方思路倒序快速冪正序快速冪代碼復雜度分析迭代實現快速冪 實現 pow(x, n) &#xff0c;即計算 x 的 n 次冪函數&#xff08;即&#xff0c;xn&#xff0…

備份MySQL數據庫的命令

備份MySQL數據庫的命令 mysqldump -hhostname -uusername -ppassword databasename > backupfile.sql 備份MySQL數據庫為帶刪除表的格式 備份MySQL數據庫為帶刪除表的格式&#xff0c;能夠讓該備份覆蓋已有數據庫而不需要手動刪除原有數據庫。 mysqldump -–add-drop-…

n位數的全排列(需要考慮大數的情況)

文章目錄題目思路代碼題目 輸入數字 n&#xff0c;按順序打印出從 1 到最大的 n 位十進制數。比如輸入 3&#xff0c;則打印出 1、2、3 一直到最大的 3 位數 999。 示例 1: 輸入: n 1 輸出: [1,2,3,4,5,6,7,8,9] 說明&#xff1a; 用返回一個整數列表來代替打印 n 為正整數 …

正則表達式匹配(動規)

文章目錄題目思路轉移方程特征再探 i 和 j代碼題目 請實現一個函數用來匹配包含 . 和 * 的正則表達式。模式中的字符 . 表示任意一個字符&#xff0c;而 * 表示它前面的字符可以出現任意次&#xff08;含0次&#xff09;。在本題中&#xff0c;匹配是指字符串的所有字符匹配整…

在循環遞增一次的數組中插入元素

文章目錄題目思路如何建立左右區間&#xff1f;如何查找最高點&#xff1f;那我們怎么判斷 num 到底處于什么樣的位置呢&#xff1f;如何確定插入位置&#xff1f;插入元素代碼題目 給一個只循環遞增一次的數組 res&#xff0c;res 滿足首元素大于等于尾元素&#xff0c;形如&…

Unable to find 'struts.multipart.saveDir' property setting.

Unable to find struts.multipart.saveDir property setting. 今天在做工作的時候遇到了這個問題&#xff0c;后來經過百度&#xff0c;終于知道了原因&#xff0c;現在記錄下來&#xff0c;以備以后查看。 1.struts.multipart.saveDir沒有配置 2.struts.multipart.saveDir用…

表示數值的字符串(有限狀態自動機與搜索)

文章目錄題目思路一代碼一思路二代碼二題目 思路一 考察有限狀態自動機&#xff08;參考jyd&#xff09;&#xff1a; 字符類型&#xff1a; 空格 「 」、數字「 0—9 」 、正負號 「 」 、小數點 「 . 」 、冪符號 「 eE 」 。 狀態定義&#xff1a; 按照字符串從左到右的…

樹的子結構

文章目錄題目深搜深搜代碼廣搜廣搜代碼題目 輸入兩棵二叉樹A和B&#xff0c;判斷B是不是A的子結構。(約定空樹不是任意一個樹的子結構) B是A的子結構&#xff0c; 即 A中有出現和B相同的結構和節點值。 例如: 給定的樹 A: 給定的樹 B&#xff1a; 返回 true&#xff0c;因為…

寫題過程中碰見的小問題

文章目錄和--vector二維vector的初始化數組中最大的數max_element()數組所有元素之和accumulate()vector數組去重對pair類型的vector排序對元素都為正整數的vector利用sort默認的升序排列進行降序排列一維數組轉二維數組size_t和int如何不用臨時變量交換兩個數?將類函數的形參…