1.迭代器頭文件:<iterator>
2.迭代器類型:
1).Input迭代器------------------------------>>>向前讀取---------------------------------->>>>>istream
2).Output迭代器--------------------------->>>向前寫入----------------------------------->>>>>ostream, inserter
3).Forward迭代器--------------------------->>>向前讀寫----------------------------------->>>>>
4).Bidirectional迭代器--------------------->>>向前向後讀寫----------------------------->>>>>List, set, multiset, map, multimap
5).Random Access迭代器---------------->>>隨機讀取寫入----------------------------->>>>>vector, deque, string, array
學習:
(1)Input迭代器
Input迭代器只能一次一次向前讀取元素,按此順序一個一個傳回元素值。(Input迭代器只能讀取元素一次,如果你複製原有的Input迭代器,使其和原來迭代器同時向前讀取元素,則返回的元素可能會不一樣。)
Input迭代器的各種操作:
表達式 | 效果 |
---|---|
*iter | 讀取實際元素 |
iter->member | 讀取實際元素成員 |
++iter | 向前步進(傳回新值) |
iter++ | 向前步進(傳回舊值) |
iter1==iter2 | 判斷迭代器是否相等 |
iter1!=iter2 | 判斷迭代是否不等 |
TYPE(iter) | 複製迭代器(copy構造函數) |
(2)Output迭代器
Output迭代器與Input迭代器剛好相反,其作用是將元素的值一個一個寫入,即,只能一個元素一個元素地賦值。
Output迭代器的操作:
表達式 | 效果 |
---|---|
*iter=value | 將數值寫到迭代器位置 |
++iter | 向前步進(傳回新值) |
iter++ | 向前步進(傳回舊值) |
TYPE(Iter) | 複製迭代器(copy構造函數) |
(3)Forward迭代器
Forward迭代器是Input和Output迭代器的組合,同時具有Input迭代器的讀取功能,還有Output迭代器的寫入功能。(和Input迭代不同的是:FOrward迭代器可以多次的指向同一羣集的同一元素,並能多次處理同一元素。)
表達式 | 效果 |
*iter | 存取實際元素 |
iter->member | 存取實際元素的成員 |
++iter | 向前步進(傳回新值) |
iter++ | 向前步進(傳回舊值) |
iter1==iter2 | 判斷是否相等 |
iter1!=iter2 | 判斷是否不等 |
TYPE() | 產生迭代器(default構造函數) |
TYPE(iter) | 複製構造函數(copy構造函數) |
iter1=iter2 | 賦值 |
(4)Bidirectional(雙向迭代器)
Bidirectional迭代器在forward迭代器基礎上增加了回頭遍歷的能力,即支持遞減運算符。
表達式 | 效果 |
---|---|
--iter | 向後步退(傳回新位置) |
iter-- | 向後步退(傳回舊位置) |
(5)Random Access(隨機存取迭代器)
Random Access 迭代器在Bidirectional迭代器基礎上面增加隨機存取能力,即提供迭代器計算能力,能加減偏移量。
以下對象和類別支持RandomAccess迭代器:
*****可隨機存取的容器:vector,deque
*****strings(字符串,string,wstring)
*****一般指針(指針)
Random Access 迭代器操作:
算式 | 效果 |
---|---|
iter[n] | 存取索引位置爲n的元素 |
iter+=n | 向前跳n個元素存取(如果n爲負值,則向後) |
iter-=n | 向後跳n個元素存取(如果n爲負值,則向前) |
iter+n | 傳回iter之後的第n個元素 |
iter-n | 傳回iter之前的第n個元素 |
iter1-iter2 | 傳回iter1與iter2之間的距離 |
iter1<iter2 | 判斷iter1 是否在iter2 之前 |
iter1>iter2 | 判斷iter1是否在iter2 之後 |
iter1<=iter2 | 判斷iter1是否不在iter2之後 |
iter1>=iter2 | 判斷iter1是否不在iter2之前 |
Vector 迭代器的遞增(Increment)和遞減(Decrement)
**一般而言,迭代器可以通過遞增和遞減來得到暫時性迭代器,但是Vector和String 就不行,Vector和String得到是暫時性指針;
(因爲Vector迭代器通常被實作爲一個一般指針;C++不允許修改基本型別(包括指針)的暫時性,但是struct 和class 則是可以的;因此如果迭代器被實化成指針,則會編譯出錯,但是如果被實化爲class ,則是會編譯通過的。deque ,List,Sets,和Maps總是可以編譯通過的,因爲迭代器不可能被實例化成指針。但是Vector就要取決於實化手法了,通常Vector會被實化爲一般指針。)
迭代器相關輔助函數:
(1)advance()可以令迭代器前進;可以使迭代器的位置增加,增加幅度由參數決定。
#include<iterator>
void advance(InputIterator& pos,Dist n);
**使名爲pos的Input迭代器步進(步退)n個元素;
**對於Bidirectional迭代器和Random Access迭代器,n可以爲負值;
**Dist 是個Template 類型,通常是整數型,因爲要進行++,--,<,等操作;
**advance()並不進行是否超序列檢查,,所以用時要注意!
(2)distance()可以處理迭代器之間的距離
#include<iterator>
Dist distance(InputIterator pos1,InputIterator pos2);
**傳回兩個迭代器pos1和pos2之間的距離;
**兩個迭代器必須指向同一個容器;
**如果不是Random Access迭代器,則必須pos1要必須能夠達到pos2位置;
**會返值Dist 的類型由迭代器決定;
(3)iter_swap()可以交換兩個迭代器之間的內容;
#include<algorithm>
void iter_swap(ForwardIterator pos1, FOrwardIterator pos2);
**交換迭代器POS1和POS2的值;
**迭代器型別不必相同,但是所指的值必須可以相互賦值;
迭代器配接器(Iterator Adapters)
(1)Reverse 逆向迭代器
Reverse迭代器是一種配接器,重新定義遞增運算、遞減運算,使其行爲正好倒置;如果你使用這樣的迭代器,算法將以逆向次序來處理元素。所有標準容器都允許使用Reverse迭代器來遍歷。
(所以這裏可以知道爲什麼前面容器的 rbegin()和rend()得到的值是那樣的;
c.rbegin(): 返回逆向迭代器;指向逆向遍歷的第一個元素;
c.rend(): 返回逆向迭代器;指向逆向遍歷的最後元素的下一個位置;
逆向迭代器與迭代器之間的關係:
rbegin()--------->>>>container::Reverse_iterator (end());
rend()----------->>>>container::Reverse_iterator (begin());
逆向迭代器與正常迭代器之間可以通過base()函數進行轉換;base()是逆向迭代器特別的成員函數;
這樣大家就可以很清楚的明白逆向迭代器與實際值得位置關係。)
(2)Insert(安插)迭代器
Insert迭代器,用來將“賦值新值”操作轉化成“安插新值”操作。算法可以執行Insert而非overwrite。
Inset迭代器操作:
算式 | 效果 |
---|---|
*iter | 無實際操作(傳回iter) |
iter=value | 安插value |
++iter | 無實際操作(傳回iter) |
iter++ | 無實際操作(傳回iter) |
Insert 迭代器分類::::C++提供3種Insert迭代器:back Inserters;front Inserters; general Inserts;
插入迭代器(Insert Iterator),又叫插入器(Inserter),是繼上次的反向迭代器之後C++中的又一個迭代器適配器。插入迭代器的主要功能爲把一個賦值操作轉換爲把相應的值插入容器的操作。插入迭代器對標準算法庫而言尤其重要。算法庫對所有在容器上的操作有個承諾:決不修改容器的大小(不插入、不刪除)。有了插入迭代器,既使得算法庫可以通過迭代器對容器插入新的元素,又不違反這一承諾,即保持了設計上的一致性。
插入迭代器提供了以下幾種操作:*itr,itr++,++itr,itr = value。但實際上,前三種操作爲“空操作”(no-op),僅僅返回itr。第四種操作itr = value纔是插入迭代器的核心,這個操作通過調用容器的成員函數(push_back(),push_front(),insert(),取決於插入器類型)把value插入到插入器對應容器的相應的位置上。
插入迭代器分爲三種類型:尾部插入器(back_insert_iterator),首部插入器(front_insert_iterator)和普通插入器(insert_iterator)。第一種通過調用容器的push_back成員函數來插入元素,因此這種插入器只對vector,list,deque和string有效。 第二種通過調用容器的push_front成員函數來插入元素,因此它只對list和deque有效。第三種通過調用insert成員函數來插入元素,並由用戶指定插入位置,它對所有標準的容器類型都有效,因爲所有容器都定義了insert成員函數。
Insert 迭代器分類:(cont 代表容器,value代表值,pos 代表迭代器位置)
名稱 | Class | 其調用函數 | 其生成函數 | |
---|---|---|---|---|
Back Inserter | back_insert_iterator | push_back(value) | back_inserter(cont) | |
Front Inserter | front_insert_iterator | push_front(value) | front_inserter(cont) | |
General Inserter | insert_iterator | insert(value) | inserter(cont,pos) |
(3)Stream iterators
Stream迭代器是一種迭代器配接器,通過它,你可以把stream當成算法的原點和終點。更明確的說,一個istream迭代器可以用來從input stream中讀元素,而一個ostream迭代器可以用來對output stream寫入元素。Stream迭代器的一種特殊形式是所謂的stream緩衝區迭代器,用來對stream緩衝區進行直接讀取和寫入操作。
Ostream迭代器可以被賦予的值寫入output stream中。
下表列出ostream迭代器的各項操作:
算式 | 效果 |
---|---|
ostream_iterator<T>(ostream) | 爲ostream產生一個ostream迭代器 |
ostream_iterator<T>(ostream,delim) | 爲ostream產生一個ostream迭代器,且各元素間以delim爲分隔符(delim的型別是const char*) |
*iter | 無實際操作(傳回iter) |
iter=value | 將value寫到ostream |
++iter | 無實際意義(傳回iter) |
iter++ | 無實際意義(傳回iter) |
以下實例來展示ostream 迭代器用法:
#include<iostream>
#include<vector>
#include<algorithm>
#include<iterator>
using namespace std;
int main()
{
ostream_iterator<int> intWriter(cout, "\n");
*intWriter = 43;
intWriter++;//無實際操作
*intWriter = 77;
intWriter = -5;
vector<int> coll;
for (int i = 1; i <= 9; ++i)
{
coll.push_back(i);
}
copy(coll.begin(), coll.end(), ostream_iterator<int>(cout, "<"));
cout << endl;
system("pause");
}
輸出:
43
77
-5
1<2<3<4<5<6<7<8<9<
istream迭代器是ostream迭代器的拍檔,用來從input
stream讀取元素。透過istream迭代器,算法可以從stream中直接讀取數據。istream迭代器的各項操作。產生一個istream迭代器時,必須提供一個input
stream作爲參數,迭代器從中讀取數據。然後它便經由input迭代器的一般接口,利用operator<<讀取數據。然而,讀取動作有可能失敗(可能到達文件尾部,或讀取錯誤),此外算法也要知道區間是否到達終點。爲解決這些問題,可以使用一個end_of_stream迭代器,可以利用默認構造函數生成。只要有任何一次讀取失敗,所有istream迭代器都會變成end_of_stream迭代器,所以進行一次讀取後, 應該將istream迭代器和end_of_stream迭代器比較一番。
算式 | 效果 |
---|---|
istream_iterator<T>() | 產生一個end-of-stream迭代器 |
istream_iterator<T>(istream) | 爲istream產生一個迭代器 |
*iter | 傳回先前讀取的值 |
iter->member | 傳回先前讀取的元素成員 |
++iter | 讀取下一個元素,並傳回其位置 |
iter++ | 讀取下一個元素,傳回迭代器指向前一個元素的位置 |
iter1==iter2 | 判斷12是否相等 |
iter1!=iter2 | 判斷12是否不等 |
#include<iostream>
#include<iterator>
using namespace std;
int main()
{
istream_iterator<int> intReader(cin);
istream_iterator<int> intReaderEOF;
while (intReader != intReaderEOF)
{
cout << "once:" << *intReader << endl;
cout << "once again:" << *intReader << endl;
++intReader;
}
system("pause");
}
輸出:字符f導致程序結束。
1 2 3 f 4
once:1
once again:1
once:2
once again:2
once:3
once again:3