STL7:迭代器总结
1、概念
迭代器是一种设计模式。容器生成的迭代器用于遍历容器中的每个元素,同时避免暴露容器的内部数据结构和实现细节
2、作用
迭代器的重要作用就是让容器和算法解耦合, 或者说让数据和操作解耦合, 算法利用迭代器作为输入, 从而摆脱对容器具体数据的访问.
3、迭代器分类
4、迭代器操作
4.1 访问
解引用*与->
下标[]
4.2 移动
5、迭代器适配器
迭代器适配器主要分三类:
(1)插入适配器
(2)流迭代器适配器:
输出流迭代器适配器ostreambuf_iterator
输入流迭代器适配器istreambuf_iterator
(3)逆向迭代器适配器reverse_iterator
5.1 插入适配器
(1)inserter.cpp
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main(){
int arr[] = {1,2,3,4,5,6};
vector<int> vec(arr,arr+6);
vector<int>:: iterator it = vec.begin();
advance(it,3);
copy(arr,arr+3,it);
copy(vec.begin(),vec.end(),ostream_iterator<int>(cout,","));
cout << endl;
copy(arr+3,arr+6,inserter(vec,it));
copy(vec.begin(),vec.end(),ostream_iterator<int>(cout,","));
}
(2)front_inserter.cpp
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
int main(){
int arr[]={1,2,3,4,5,7};
list<int> vec(5);
ostream_iterator<int> os_it(cout,",");
copy(arr,arr+3,front_inserter(vec));
copy(vec.begin(),vec.end(),os_it);
}
(3)back_inserter.cpp
#include <iostream>
#include <list>
#include <iterator>
using namespace std;
int main(){
int arr[]={1,2,3,4,5,7};
list<int> vec(5);
ostream_iterator<int> os_it(cout,",");
copy(arr,arr+3,back_inserter(vec));
copy(vec.begin(),vec.end(),os_it);
}
5.2 流迭代器适配器
(1)输出流迭代器适配器ostreambuf_iterator
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main(){
int arr[]={1,2,3,4,5,6};
ostream_iterator<int> os_it(cout,",");
copy(arr,arr+6,os_it);
vector<int> vec(arr,arr+6);
ostream_iterator<int> os_it2(cout,",");
copy(vec.begin(),vec.end(),os_it2);
}
(2)输入流迭代器适配器istream_iterator
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main(){
istream_iterator<int> eos;
istream_iterator<int> is_it(cin);
ostream_iterator<int> os_it(cout,",");
int arr[10];
copy(is_it,eos,arr);
copy(arr,arr+10,os_it);
cout << endl;
cin.clear(); // 注意这里要清除
vector<int> vec;
copy(istream_iterator<int>(cin),eos,back_inserter(vec));
copy(vec.begin(),vec.end(),os_it);
}
(3)逆向迭代器适配器reverse_iterator
**逆向迭代器适配器:template class
reverse_iterator;**
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main(){
int arr[]={1,2,3,4,5,6};
vector<int> vec(arr,arr+6);
copy(vec.begin(),vec.end(),ostream_iterator<int>(cout,","));
cout << endl;
copy(
reverse_iterator<vector<int>::iterator>(vec.end()),
reverse_iterator<vector<int>::iterator>(vec.begin()),
ostream_iterator<int>(cout,","));
cout << endl;
}
6、迭代器对比
7、练习
(1)空白符分割字符串
#include <vector>
#include <iterator>
#include <sstream>
using namespace std;
vector<string> split(const string &str){
using isiterator = istream_iterator<string>;
vector<string> vec;
istringstream iss(str);
copy(isiterator(iss),isiterator(),back_inserter(vec));
return vec;
}
(2)list和vector的对比
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main(){
vector<int> vec = {1,2,3,4,5,6,7};
list<int> li;
copy(vec.begin(),vec.end(),back_inserter(li));
for(auto n:li){
cout << n << ' ';
}
cout << endl;
auto vec_it = vec.begin();
auto li_it = li.begin();
cout << *vec_it << " " << endl;
cout << *li_it << " " << endl;
vec_it=vec_it+4;
advance(li_it,4);
cout << *vec_it << " " << *li_it<< endl;
}
(3)仿函数相关
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Test{
int n,m;
public:
Test(int n,int m):n(n),m(m){}
int operator()(){
return n+m;
}
int operator()(int h){
return n+m+h;
}
};
//函数指针
bool cmp(int a,int b){
return a>b;
}
//类模板
template<class T>
class Compare{
public:
bool operator()(T a,T b){
return a>b;
}
};
//函数模板
template<typename T>
bool compare(T a,T b){
return a>b;
}
int main(){
Test t(1,2);
cout << t.operator()() << endl;//完全体
cout << t() << endl;//简写
cout << t(3) << endl;//t.operator()(3)
cout << t.operator()(3) << endl;
cout << Test(4,5).operator()(6) << endl; //匿名对象调用
cout << Test(4,5)(6) << endl;
vector<int> vec = {2,4,6,1,3,5};
sort(vec.begin(),vec.end(),cmp);//函数指针
sort(vec.begin(),vec.end(),Cmp());//仿函数
sort(vec.begin(),vec.end(),Compare<int>());//类模板仿函数
sort(vec.begin(),vec.end(),Compare<int>);//函数模板
for (auto c :vec){
cout << c << " ";
}
cout << endl;
sort(vec.begin(),vec.end(),less<int>());//升序 标准库STL
for (auto c :vec){
cout << c << " ";
}
cout << endl;
sort(vec.begin(),vec.end(),greater<int>());//降序
for (auto c :vec){
cout << c << " ";
}
}
(4)lambda表达式
#include <iostream>
#include <vector>
#include<algorithm>
#include <list>
using namespace std;
void Print(int n){
cout << n << " ";
}
struct CPrint{
void operator()(int n){
cout << n << " ";
}
};
//for_each的工作原理:函数模板
template<class It,class F>
void For_Each(It first,It last,F func){
while(first != last){
func(*first);
++first;
}
}
int main(){
list<int> vec = {1,3,4,5,6,7,8,9};
//for_each专用函数,循环
for_each(vec.begin(),vec.end(),Print);
cout << endl;
For_Each(vec.begin(),vec.end(),CPrint());
cout << endl;
For_Each(vec.begin(),vec.end(),CPrint());
cout << endl;
//C++11 lambda表达式
auto print = [](int n){
cout << n << " ";
};
print(100);
cout << endl;
for_each(vec.begin(),vec.end(),print);
cout << endl;
for_each(vec.begin(),vec.end(),[](int n){cout << n << ' ';});
cout << endl;
}
(5)transform
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>//accumulate的头文件
using namespace std;
int Plus10(int n){
return n*10;
}
int main(){
vector<int> vec = {1,2,3,4,5,6};//c++11的写法
vector<int> res(vec.size());
transform(vec.begin(),vec.end(),res.begin(),[](int n){return n*10;});
for(auto n:res){
cout << n << " ";
}
cout << endl;
transform(vec.begin(),vec.end(),res.begin(),vec.begin(),[](int n,int m){return n+m;});
for(auto n:vec){
cout << n << " ";
}
cout << endl;
cout << count_if(vec.begin(),vec.end(),[](int n){return n%2==0;}) << endl;
vec.push_back(11);
for(auto n:vec){
cout << n << " ";
}
cout << endl;
//remove没有真正删除数据 而是把要删除的数据都放在了后面,返回删除数据的迭代器
auto last = remove(vec.begin(),vec.end(),11);
vec.erase(last,vec.end());//真正的删除
for(auto n:vec){
cout << n << " ";
}
cout << endl;
//这个是删除里面所有偶数的方法
//返回条件为真的全部删除
/*auto last = remove_if(vec.begin(),vec.end(),[](int n){return n%2==0;});
vec.erase(last,vec.end());//真正的删除
for(auto n:vec){
cout << n << " ";
} */
for(auto n:res){
cout << n << " ";
}
cout << endl;
auto last1 = remove_copy_if(vec.begin(),vec.end(),res.begin(),[](int n){return n%2==0;});
res.erase(last1,res.end());
for(auto n:res){
cout << n << " ";
}
cout << endl;
cout << accumulate(res.begin(),res.end(),0) << endl;
cout << accumulate(res.begin(),res.end(),1,[](int res,int n){return res*n;}) << endl;
}