插入、流和反向迭代器

  • 2019 年 11 月 3 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/Enterprise_/article/details/102826928

插入迭代器

類型和不同

用於向容器插入元素,一共有三種,back_inserter,front_insert和inserter;

back_inserter需要容器支援push_back,功能就是創建一個使用push_back的迭代器,元素插入到之後

front_inserter需要容器支援front_back,功能創建一個能使用push_front的迭代器,元素會被插入到容器首部

inserter接受兩個參數,創建一個使用insert的迭代器,元素會被插入到給定迭代器的元素之前

example

#include<bits/stdc++.h>  using namespace std;  void print(list<int>v) {  	for_each(v.cbegin(), v.cend(), [](int a) {cout << a << " "; });  	cout << endl;  }  int main(void) {    	list<int>vec{1,1,1,2,2,2,3,3,3};  	list<int>v1{ 666,777 }, v2, v3, v4;  	v3 = v4 = v1;  	unique_copy(vec.cbegin(), vec.cend(), inserter(v1, v1.begin()));  	unique_copy(vec.cbegin(), vec.cend(), back_inserter(v3));  	unique_copy(vec.cbegin(), vec.cend(), front_inserter(v4));  	unique_copy(vec.cbegin(), vec.cend(), back_inserter(v2));  	print(v1);  	print(v3);  	print(v4);  	print(v2);      return 0;  }

上面的程式碼結果如下:

1 2 3 666 777  666 777 1 2 3  3 2 1 666 777  1 2 3

將vec中的元素分別用三種插入迭代器進行不重複複製的時候就可以看到三種迭代器的不同之處,即插入位置的不同。

流迭代器

類型和要求

istream_iterator讀取輸入流,而ostream_iterator向一個輸出流寫入數據。

用流迭代器時,必須指定迭代器將要讀寫的元素類型,同時要求所讀寫的元素必須支援對應的運算符,istream_iterarot要求>>,另一個要求<<。

創建方式

istream_iterator<T>in(ins); //in從輸入流ins中讀取類型為T的值  istream_iterator<T>eof;	//istream_iterator<T>eof();時,此時的eof就相當於指向EOF標誌的迭代器,名字任意  ostream_iterator<T>out(oos);//out將類型為T的值寫入到輸出流oos中  ostream_iterator<T>out(oos,str);//在寫入數據到輸出流的基礎上,在每個值的後面都加上一個字元串str,str只能是一個C風格的字元串

結合文件操作,如下程式碼:

#include<bits/stdc++.h>  using namespace std;  int main(void) {      ofstream out("afile.txt",ofstream::out);//以out模式打開文件  	ifstream fin("afile.txt");//輸入文件流關聯afile.txt文件  	istream_iterator<string>in(cin),eof;//將輸入流迭代器綁定到標準輸入流中  	ostream_iterator<string>put(out," ");//將輸出流迭代器綁定到文件輸出流out中,並且每個值後面都輸出一個空格  	vector<string> s1, s2;      while (in != eof) {	//從遞增輸入流中讀取數據,解引用後放入s1中  		s1.push_back(*in++);  	}  	for (auto i : s1)  		*put++ = i;//將s1中的元素通過put輸出到文件中  	out << endl;//刷新緩衝區  	in = fin;//將迭代器重新綁定到文件輸入流中  	while (in != eof) {////從遞增輸入流中讀取數據,解引用後放入s2中  		s2.push_back(*in++);  	}  	for (auto i : s2)cout << i << " "; cout << endl;//列印s2中的元素  	return 0;  }

上述程式碼即從標準輸入流中讀入數據到s1中,然後將s1中的數據輸出到文件里,再從文件里讀取數據到s2,在輸出到螢幕上。雖然沒什麼用,卻還是能體現出流迭代器的作用,但是仍然比較繁瑣,和標準庫演算法結合起來,迭代器才更加強大。

#include<bits/stdc++.h>  using namespace std;  int main(void) {      ofstream out("afile.txt",ofstream::out);//以out模式打開文件  	ifstream fin("afile.txt");//輸入文件流關聯afile.txt文件  	istream_iterator<string>in(cin),eof;//將輸入流迭代器綁定到標準輸入流中  	ostream_iterator<string>put(out," ");//將輸出流迭代器綁定到文件輸出流out中,並且每個值後面都輸出一個空格  	vector<string> s1(in, eof);//利用迭代器構造vector  	copy(s1.begin(), s1.end(), put);//copy演算法將s1中的元素通過put輸出到文件中  	out << endl;//刷新緩衝區  	in = fin;//將迭代器重新綁定到文件輸入流中  	vector<string> s2(in, eof);//利用迭代器構造vector  	copy(s2.begin(), s2.end(), ostream_iterator<string>(cout," "));  	return 0;  }

這樣來循環都不用寫了,用copy就能完成輸出,上面的輸出流也能重新綁定,

反向迭代器

類型和操作

反向迭代器是在容器中從尾部元素向首部元素反向移動的迭代器。同時遞加和遞減操作會顛倒,遞增為向前一個元素移動,即向首部移動;遞減為向後一個移動,即向尾部移動。

除了forward_list之外其他容器都支援反向迭代器。

反向迭代器有rbegin,rend,crbegin和crend;

四種迭代器指向的容器位置如下所示:

example

逆序列印vector

	vector<string>vt{ "aa","bb","cc" };  	copy(vt.crbegin(), vt.crend(), ostream_iterator<string>(cout," "));

輸出為

cc bb aa

同樣如果只有一個string,就會反向列印這個string的字元,因為反向迭代器會反向操作容器中的元素

	string str = "apple,dinner";  	cout << string(str.crbegin(), str.crend()) << endl;

輸出為

rennid,elppa

反向迭代器的轉換

反向迭代器可以用自帶的base成員函數來轉換為一個普通正向迭代器;

	string str = "apple,dinner";  	cout << string(str.crend().base(), str.crbegin().base()) << endl;

輸出為

apple,dinner

轉換後的迭代器和原來的迭代器表示的範圍是一樣的,即

[crbegin(),crend())和[crend().base(), crbegin().base())

這兩者的元素範圍相同,但是轉換前後的迭代器指向的不是同一個元素。具體表示如下圖!