1、五种迭代器。
输入迭代器重载 *、== 、!= 、前置++、后置++运算符。STL提供的主要输入迭代器是 istream_iterator 。
它有两种构造函数:
istream_iterator() :创建一个流结束的迭代器
istream_iterator(istream& ):参数是输入流,含义是从输入流中读数据,当遇到流结束符时停止。
#include <iostream> #include <iterator> using namespace std; int main() { cout<<"Please Input(int): "<<endl; istream_iterator<int> a(cin); istream_iterator<int> b; while(1) { cout<<*a<<endl; a++; if(a == b) { cout<<"break"<<endl; break; } } }
输出迭代器:
输出迭代器重载 *、=、前置++、后置++运算符。STL提供的主要输入迭代器是 ostream_iterator 。
它有两种构造函数:
ostream_iterator(ostream& ) :创建一个流输出迭代器,用来迭代out输出流。
ostream_iterator(ostream& ,const char* delim):同上,只是输出的数据之间用 delim 字符串分隔。
#include <iostream> #include <iterator> using namespace std; int main() { ostream_iterator<int> ostream_it(cout,"\t"); for(int i = 0;i < 5; i++) { *ostream_it = i; ostream_it++; } return 0; }
前向迭代器:包含了输入和输出迭代器两者的所有功能,加上还可以多次解析一个迭代器指定的位置,因此可以对一个值进行多次读写。顾名思义,前向迭代器只能向前移动,但是STL本身并没有为专为前向迭代器预定义的迭代器。
双向迭代器:包含了前向迭代器的所有功能,另外它还可以利用自减操作符向后移动一个位置。例如 list 容器需要的就是双向迭代器。
随机访问迭代器:具有双向迭代器的所有功能,再加上一个指针所有的功能。包括使用操作符operate[]进行索引,加某个整数值到一个指针就可以向前或向后移动若干位置,或者使用比较运算符在迭代器之间进行比较。比如 vector 容器需要的就是该类迭代器。
在一切情况下,都可以使用需求最细的随机访问迭代器,但过多的需求会降低它的效率。所以实际编程时应该选择正好合适的iterator以期得到最高的效率。
文件读写:无论读写,文件不存在时都不会报异常。如果文件不存在,读时数据为空,写时创建新文件。
文件读取:
#include <iostream> #include <fstream> using namespace std; int main() { //write file: string filename = "hello.cpp"; ofstream fout; fout.open(filename.c_str()); //ofstream fout(filename.c_str(),ios::app); //使用构造函数,可以判断文件是否存在。如果用构造函数还是open(),文件不存在时,都可以自动创建。 //if(!fout) //{ // cout<<"file not found!create a new file."<<endl; //} fout<<"Key"<<"\t"<<"Value"<<endl;
fout.close(); //read file: ifstream fin(filename.c_str()); string str; while(getline(fin,str)) //按行读取(以\n为间隔符)。也可以 while(fin>>str) 这是以空格间隔符读取
{ cout<<str<<endl; }
fin.close(); return 0; }
二进制文件读写:
#include <iostream> #include <fstream> using namespace std; struct User { int id; char name[20]; }; int main() { User user1={1,"yugd"}; User user2; string filename = "test.dfd"; ofstream ofs(filename.c_str()); ofs.write((const char*)&user1,sizeof(User)); ofs.close(); ifstream ifs(filename.c_str()); ifs.read((char*)&user2,sizeof(User)); cout<<"id: "<<user2.id<<"\tname: "<<user2.name<<endl; ifs.close(); return 0; }
输入输出流缓冲:
#include <iostream> #include <fstream> using namespace std; int main() { string filename = "test.cpp"; ifstream ifs(filename.c_str()); cout<<ifs.rdbuf();
ifs.close(); return 0; }
定位输入输出流:
函数对象:
必须重载 operator() 函数,函数对象调用方式为直接采用构造函数形式。
#include <iostream> #include <vector> using namespace std; int sum = 0; void f(int n) { sum += n; } class SumClass { public: SumClass():sum(0){} void operator()(int n) { sum += n; } int getSum(){return sum;} private: int sum; }; template <typename T> class TSumClass { public: TSumClass():sum(0){} void operator()(T n) { sum += n; } T getSum(){return sum;} private: T sum; }; int main() { vector<int> vect; for(int i= 1;i<= 100;i++) vect.push_back(i); for_each(vect.begin(),vect.end(),f); cout<<"sum: "<<sum<<endl; //5050 SumClass obj = for_each(vect.begin(),vect.end(),SumClass()); //直接采用构造函数形式调用。 cout<<"obj.getSum(): "<<obj.getSum()<<endl; //5050 TSumClass<int> tobj = for_each(vect.begin(),vect.end(),TSumClass<int>()); cout<<"tobj.getSum(): "<<tobj.getSum()<<endl; //5050 }
merge():合并两个排序列表;
splice():拼接两个列表;
sort():列表的排序;
#include <list> #include <iostream> int main() { int array1[4] = {1,5,3,10}; int array2[4] = {2,8,6,9}; std::list<int> lt1(array1,array1+4),lt2(array2,array2+4); lt1.sort(); lt2.sort(); //lt1.splice(lt1.begin(),lt2); //2,6,8,9,1,3,5,10 lt1.merge(lt2); //1,2,3,5,6,8,9,10 }
queue(队列,先进先出)与stack(栈,后进先出)的构造函数:
queue(class T,class Container = deque<T>);
stack(class T,class Container = deque<T>);
其默认容器都是deque.
priority_queue 默认容器是 vector.
队列独有的函数:T& front(); T& back();
堆栈独有的函数:T& top(); 返回栈顶元素,其实类似于 back();
容器适配器只是基础容器类的再封装,不是重新定义。
queue 可以使用 deque 和 list 做为基础容器(vector 没有 pop_front 方法), stack 可以使用 deque、 list 和 vector 做为基础容器。
再谈迭代器:
非变异算法列表:
变异算法列表:
排序及相关函数列表: