1 / 25

STL-2

第十九章. STL-2. 回顾. 泛型程序设计 与标准模板库有关的概念和术语 C++ 标准模板库中的容器. 目标. 迭代器 函数对象 标准 C++ 库中的泛型算法. 迭代器. 迭代器是面向对象版本的指针 指针可以指向内存中的一个地址 迭代器可以指向容器中的一个位置 STL 的每一个容器类模版中,都定义了一组对应的迭代器类。使用迭代器,算法函数可以访问容器中指定位置的元素,而无需关心元素的具体类型。. begin(). end(). elem[0]. elem[1]. …. elem[n-1]. 迭代器的类型. 输入迭代器

Download Presentation

STL-2

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第十九章 STL-2

  2. 回顾 • 泛型程序设计 • 与标准模板库有关的概念和术语 • C++标准模板库中的容器

  3. 目标 • 迭代器 • 函数对象 • 标准C++库中的泛型算法

  4. 迭代器 • 迭代器是面向对象版本的指针 • 指针可以指向内存中的一个地址 • 迭代器可以指向容器中的一个位置 • STL的每一个容器类模版中,都定义了一组对应的迭代器类。使用迭代器,算法函数可以访问容器中指定位置的元素,而无需关心元素的具体类型。 begin() end() elem[0] elem[1] … elem[n-1]

  5. 迭代器的类型 • 输入迭代器 • 可以用来从序列中读取数据 • 输出迭代器 • 允许向序列中写入数据 • 前向迭代器 • 既是输入迭代器又是输出迭代器,并且可以对序列进行单向的遍历 • 双向迭代器 • 与前向迭代器相似,但是在两个方向上都可以对数据遍历 • 随机访问迭代器 • 也是双向迭代器,但能够在序列中的任意两个位置之间进行跳转

  6. 迭代器的类型表

  7. #include <list> #include <iostream> using namespace std; int main(){ int i,key; list<int> intList; list<int>::iterator it; cout<<"input 5 digit:"; for(i=0;i<5;i++){ cin>>key; intList.push_front(key); } cout<<"data list:"<<endl; it=intList.end(); while(1){ cout.width(6); cout<<*(--it); if(it==intList.begin()) break; } return 0; } 迭代器的使用

  8. 函数对象 • 一个行为类似函数的对象,它可以没有参数,也可以带有若干参数,其功能是获取一个值,或者改变操作的状态。 • 任何普通的函数和任何重载了调用运算符operator()的类的对象都满足函数对象的特征 • STL中也定义了一些标准的函数对象,如果以功能划分,可以分为算术运算、关系运算、逻辑运算三大类。为了调用这些标准函数对象,需要包含头文件<functional>。

  9. 已集成的函数对象 可以自己编写一个函数作 为算法的参数

  10. #include <iostream> using namespace std; class CFunObj{ public: void operator()(){ cout<<"hello,function object!"<<endl; } int operator()(int i){ cout<<"hello, function object other!"<<endl; return i+1; } private: int dat; }; void main(){ CFunObj fo; fo(); cout<<fo(1)<<endl; //CFunObj()(); } 自定义函数对象

  11. 标准C++库中的算法 • 算法本身是一种函数模板 • 不可变序列算法(non-mutating algorithms) • 不直接修改所操作的容器内容的算法 • 可变序列算法(mutating algorithms) • 可以修改它们所操作的容器的元素。 • 算法部分主要由头文件<algorithm>,<numeric>和<functional>组成

  12. STL算法的头文件 • <algorithm>是所有STL头文件中最大的一个,它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。 • <numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。 • <functional>中则定义了一些模板类,用以声明函数对象。

  13. 标准函数6-1

  14. 标准函数6-2

  15. 标准函数6-3

  16. 标准函数6-4

  17. 标准函数6-5

  18. 标准函数6-6

  19. 泛型算法例子3-1 #include <iostream> #include <vector> #include <algorithm> #include <iterator> #include <numeric> #include <functional> using namespace std; int main(){ int ia[] = { 1, 2, 3, 4, 5, 7, 9, 11 }; vector<int> iv(ia, ia+8); //累加,52 cout<<accumulate(iv.begin(),iv.end(),10)<<endl; //相邻差值 adjacent_difference(iv.begin(),iv.end(),iv.begin()); //复制到ostream_iterator 去, 每列印一个元素, 即加上一个空格

  20. 泛型算法例子3-2 copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, “ ”)); // 1 1 1 1 1 2 2 2 //计算元素值为2 的个数 cout << count(iv.begin(), iv.end(), 2) << endl; // 3 //计算奇数元素的个数 cout << count_if(iv.begin(), iv.end(), bind2nd(modulus<int>(),2)) << endl; // 5 //从头开始填入新值7, 填3 次 fill_n(iv.begin(), 3, 7); copy(iv.begin(), iv.end(), ostream_iterator<int>(cout,“ ”)); // 7 7 7 1 1 2 2 2 //内积, 7*7 + 7*7 + 7*7 + 1*1 + 1*1 + 2*2 + 2*2 + 2*2 cout << inner_product(iv.begin(), iv.end(), iv.begin(),0) << endl; //161

  21. 泛型算法例子3-3 //排序 sort(iv.begin(), iv.end()); copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, “ ”)); // 1 1 2 2 2 7 7 7 //顛倒元素次序 reverse(iv.begin(), iv.end()); copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, “ ”)); // 7 7 7 2 2 2 1 1 //旋转, 交换[first, middle)和[middle, last) rotate(iv.begin(), iv.begin()+3, iv.begin()+6); copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, “ ”)); // 2 2 2 7 7 7 1 1 }

  22. #ifndef CMYCLASS_H #define CMYCLASS_H #include <string.h> class CMyClass{ public: CMyClass(); CMyClass(string name,int age); friend bool Less(const CMyClass &num,const CMyClass &myclass); bool operator==(const CMyClass &myclass); string &GetName(); int GetAge(); private: string m_name; int m_age;};#endif CMyClass::CMyClass(){ m_name=""; m_age=12; } CMyClass::CMyClass(string name,int age) { m_name=name; m_age=age; } bool CMyClass::operator==(const CMyClass &myclass){ return m_name==myclass.m_name; } string & CMyClass::GetName(){ return m_name;} int CMyClass::GetAge(){ return m_age;} 自定义函数作为算法参数3-1

  23. 自定义函数作为算法参数3-2 #include "MyClass.h" #include <iostream> #include <algorithm> #include <vector> #include <functional> #include <numeric> using namespace std; bool Less(const CMyClass &num,const CMyClass &myclass){ return num.m_name<myclass.m_name; } void PrintMyClass(CMyClass &myclass){ cout<<"name:"<<myclass.GetName()<<"\t age:"<<myclass.GetAge()<<endl; } bool SearchByName(CMyClass &myclass){ return myclass.GetName()=="AAAAZ"; }

  24. 自定义函数作为算法参数3-3 void main(){ CMyClass myclass; vector<CMyClass> vec; vec.push_back(CMyClass("AAAA",12)); vec.push_back(CMyClass("DFKASDF",12)); vec.push_back(CMyClass("ASDFSAFA",12)); vec.push_back(CMyClass("Z",12)); vec.push_back(CMyClass("AAAAZ",12)); vec.push_back(CMyClass("DFKSADFZ",12)); sort(vec.begin(),vec.end(),Less); // for (vector<CMyClass>::iterator it=vec.begin();it!=vec.end();it++){ // cout<<it->GetName()<<endl;} for_each(vec.begin(),vec.end(),PrintMyClass); vector<CMyClass>::iterator r=find_if(vec.begin(),vec.end(),SearchByName); cout<<(*r).GetName()<<endl; }

  25. 总结 • 迭代器 • 函数对象 • 标准C++库中的算法 • 自定义函数作为算法参数

More Related