相关视频——黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难 -(167-263)
基础部分(1-83)—— 如果你准备学习C++,并且有C语言的基础,我希望你能简单的过一遍知识点。 
核心部分(84-146)—— C++核心编程部分 
案例1(147-166)——职工管理系统—— C++实现职工管理系统 
 
 
C++提高编程 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层次的使用
模板 模板的概念 模板就会通用的模具,大大提高复用性。
例如生活中的一寸照片、PPT模板。
模板的特点 :
模板不可以直接使用,它只是一个框架 
模板的通用并不是万能的 
 
函数模板 
C++另一种编程思想称为泛型编程 ,主要利用的技术就是模板 
C++提供两种模板机制,函数模板 和类模板 。 
 
函数模板语法 函数模板作用: 建立一个通用的函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型 来代表。
语法 :
1 2 template <typename  T>函数声明或定义 
 
解释 : template——声明创建模板
typena me——表明其后面的 符号为一种数据类型,可以用class代替。
T——通用的数据类型,名称可以替换,通常为大写字母。        
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream>  using  namespace  std ;void   SwapInt (int  &a, int  &b)  {	int  temp = b; 	b = a; 	a = temp; } void  SwapDouble (double  &a,double  & b)  {	double  temp = a; 	a = b; 	b = temp; } template <typename  T>void  MySwap (T& a, T& b)  {	T Temp = a; 	a = b; 	b = Temp; } void  test01 ()  {	int  a = 10 ; 	int  b = 20 ; 	 	 	MySwap(a, b); 	cout  << a  << endl ; 	cout  << b << endl ; 	double  c = 11.1 ; 	double  d = 12.2 ; 	 	MySwap<double >(c, d); 	cout  << c << endl ; 	cout  << d << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
函数模板利用关键字template 
使用函数类型模板有两种方式:自动类型推导、显示指定类型 
模板的目的是为了提高复用性,将类型参数化 
 
函数模板注意事项 注意事项 :
自动类型推导,必须推导出一致的数据类型T才能使用 
模板必须要确定出T的数据类型,才可以使用 
 
函数模板案例 案例描述 :
利用函数模板封装一个排序的函数,可以对不用数据类型数组进行排序 
排序规则从大到小,排序算法为选择排序 
分别利用char数组和int数组进行测试 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <iostream>  using  namespace  std ;template <class  T >void  mySwap (T& a, T& b)  {	T temp = a; 	a = b; 	b = temp; } template <class  T >void  mySort (T arr[],int  len)  {	for  (int  i =  0 ; i < len; i++) 	{ 		int  max = i; 		for  (int  j = i + 1 ; j < len; j++) 		{ 			 			if  (arr[max] < arr[j]) 			{ 				max = j; 			} 		} 		if  (max != i) 		{ 			 			mySwap(arr[max], arr[i]); 		} 	} } template <class  T >void  myPrint (T arr[], int  len)  {	for  (int  i = 0 ; i < len; i++) 	{ 		cout  << arr[i]<< endl ; 	} } void  test01 ()  {	char  charArr[] = "badcfe" ; 	int  num = sizeof (charArr) / sizeof (char ); 	mySort(charArr, num); 	myPrint(charArr, num); } void  test02 ()  {	int  intArr[] = {2 ,3 ,78 ,9 ,7 }; 	int  num = sizeof (intArr) / sizeof (int ); 	mySort(intArr, num); 	myPrint(intArr, num); } int  main (void )  {	test01();  	test02(); 	return  0 ; } 
 
普通函数与函数模板的区别 普通函数与函数模板的区别 :
普通函数调用时可以发生自动类型转换(隐式类型推导) 
函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换 
如果利用显式指定类型的方式,可以发生隐式类型转换 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream>  using  namespace  std ;int  myAdd01 (int  a, int  b)  {	return  a + b; } template <class  T >T myAdd02 (T a, T b)   {	return  a + b; } void  test01 ()  {	int  a = 10 ; 	int  b = 20 ; 	char  c = 'c' ; 	cout  << myAdd01(a, c) << endl ; 	 	 	 	cout  << myAdd02<int >(a, c) << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :建议使用显式指定类型的方式,调用函数模板,因为可以自己确定通用类型T
普通函数与函数模板的调用规则 调用规则如下:
如果函数模板和普通函数都可以实现,优先调用普通函数 
可以通过空模板参数列表来强制调用函数模板 
函数模板也可以发生重载 
如果函数模板可以产生更好的匹配,优先调用函数模板 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream>  using  namespace  std ;void  myPrint (int  a, int  b)  {	cout  << "调用普通函数"  << endl ; } template <class  T >void  myPrint (T a, T b)  {	cout  << "调用模板"  << endl ; } template <class  T >void  myPrint (T a, T b,T c)  {	cout  << "调用重载模板"  << endl ; } void  test01 ()  {	int  a = 10 ; 	int  b = 20 ; 	 	myPrint(a, b); 	 	myPrint<>(a,b); 	 	myPrint(a, b, 100 ); 	 	char  c1 = 'a' ; 	char  c2 = 'b' ; 	myPrint(c1, c2); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性。
模板的局限性 局限性 :
模板的通用性并不是万能的。
1 2 3 4 5 template <class  T >void  f (T a,T b)  {    a = b; } 
 
在上述代码中提供的赋值操作,如果传入的a和b是一个数组,就无法实现了。
 再例如 :
1 2 3 4 5 6 template <class  T >void  f (T a,T b)  {    if (a>b)     {......} } 
 
在上述代码中,如果T的数据类型传入的是像Person这样的自定义类型,也无法正常运行。
因此C++为了解决这种问题,提供模板的重载,可以为这些特定的类型 提供具体化 的模板。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 #include <iostream>  #include <string>  using  namespace  std ;class  Person { public :	Person(string  name,int  age) 	{ 		this ->m_Name = name; 		this ->m_Age = age; 	} 	string  m_Name; 	int  m_Age; }; template <class  T >bool  myCompare (T& a, T& b)  {	if  (a == b) 	{ 		return  true ; 	} 	else  	{ 		return  false ; 	} } template <>bool  myCompare (Person& p1, Person& p2)  {	if  (p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age) 	{ 		return  true ; 	} 	else  	{ 		return  false ; 	} } void  test01 ()  {	int  a = 10 ; 	int  b = 20 ; 	bool  ret = myCompare(a, b); 	if  (ret) 	{ 		cout  << "相等"  << endl ; 	} 	else  	{ 		cout  << "不相等"  << endl ; 	} } void  test02 ()  {	Person p1 ("Tom" , 10 )  ; 	Person p2 ("Tom" , 10 )  ; 	bool  ret = myCompare(p1, p2); 	if  (ret) 	{ 		cout  << "相等"  << endl ; 	} 	else  	{ 		cout  << "不相等"  << endl ; 	} } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 :
利用具体化的模板,可以解决自定义类型的通用化 
学习模板并不是为了写模板,而是在STL能够运用系统系统的模板 
 
(知道模板怎么写,并且会有别人写好的模板就可以了。)
类模板 类模板语法 类模板作用:
建立一个通用类, 类中成员数据可以不具体指定,用一个虚拟的类型来代表 
 
语法: 
 
解释 :
template< typename  T>——声明创建模板
typename——表明其后面的符号是一种数据类型,可以用class代替
T——通用的数据类型,名称可以替换,通常为大写字母
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream>  #include <string>  using  namespace  std ;template <class  NameType ,class  AgeType >class  Person { public :	Person(NameType name, AgeType age) 	{ 		this ->m_Age = age; 		this ->m_Name = name; 	} 	void  showPerson ()  	 {		cout  << this ->m_Name << this ->m_Age << endl ; 	} 	NameType m_Name; 	AgeType m_Age; }; void  test01 ()  {	 	Person<string , int >p1("张三" ,10 ); 	p1.showPerson(); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
类模板和函数模板语法相似,在声明模板template后面加类,次类称为类模板。
类模板与函数模板的区别 类模板与函数模板的区别主要有两点:
类模板没有自动类型推导的使用方式 
类模板在模板参数列表中可以有默认参数 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream>  #include <string>  using  namespace  std ;template <class  NameType , class  AgeType  =  int >class  Person { public :	Person(NameType name,AgeType age) 	{ 		this ->m_Name = name; 		this ->m_Age = age; 	} 	void  ShowPerson ()  	 {		cout  << this ->m_Name << this ->m_Age << endl ; 	} 	NameType m_Name; 	AgeType m_Age; }; void  test01 ()  {	 	Person<string ,int >p("李四" , 13 ); 	p.ShowPerson(); } void  test02 ()  {	Person<string >p2("张三" , 13 ); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
类模板使用只能用显式指定类型方式 
类模板中的模板参数列表可以有默认参数 
 
类模板中的成员函数创建实际 类模板中成员函数和普通类中成员函数创建实际是有区别的:
普通类中的成员函数一开始就可以创建 
类模板中的成员函数在调用时才创建 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream>  #include <string>  using  namespace  std ;class  Person1  { public :	void  showPerson1 ()  	 {		cout  << "Person show1"  << endl ; 	} }; class  Person2 { public :	void  showPerson2 ()  	 {		cout  << "Person show2"  << endl ; 	} }; template <class  T >class  MyClass { public :	T obj; 	 	void  func1 ()  	 {		obj.showPerson1(); 	} 	void  func2 ()  	 {		obj.showPerson2(); 	} }; void  test01 ()  {	MyClass<Person2>m; 	m.func1(); 	 } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 类模板中的成员函数并不是一开始就创建的,在调用时才去创建。
类模板对象做函数参数 学习目标:类模板实例化出的对象,向函数传参的方式 
一共有三种传入方式
指定传入的类型——直接显式对象的数据类型 
参数模板化——将对象中的参数变为模板参数进行传递 
整个类模板化——将这个对象类型,模板化进行传递 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 #include <iostream>  using  namespace  std ;template <class  T1 ,class  T2 >class  Person { public :	Person(T1 name,T2 age) 	{ 		this ->m_Name = name; 		this ->m_Age = age; 	} 	void  showPerson ()  	 {		cout  << this ->m_Name << this ->m_Age << endl ; 	} 	T1 m_Name; 	T2 m_Age; }; void  PrintPerson1 (Person<string ,int >&p)  {	p.showPerson(); } void  test01 ()  {	Person<string , int >p1("张三" ,11 ); 	PrintPerson1(p1); } template <class  T1 ,class  T2 >void  PrintPerson2 (Person<T1, T2>&p)  {	p.showPerson(); 	cout  << "T1的数据类型为"  << typeid (T1).name() << endl ; 	cout  << "T2的数据类型为"  << typeid (T2).name() << endl ; } void  test02 ()  {	Person<string , int >p2("李四" , 12 ); 	PrintPerson2(p2); } template <class  T >void  PrintPerson3 (T &p)  {	p.showPerson(); 	cout  << "T的数据类型为"  << typeid (T).name() << endl ; 	 } void  test03 ()  {	Person<string , int >p3("赵四" , 14 ); 	PrintPerson3(p3); } int  main (void )  {	test01(); 	test02(); 	test03(); 	system("pause" ); 	return  0 ; } 
 
总结 :
通过类模板创建的对象,可以有三种方式向函数中进行传参 
使用比较广泛得是第一种,指定传入的类型 
 
类模板与继承 当类模板碰到继承时,需要注意一下几点:
当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型 
如果不想指定,编译器无法给子类分配内存‘ 
如果想灵活指定出父类中T的类型,子类也需要变为类模板 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream>  using  namespace  std ;template <class  T >class  Base { 	T m; }; class  Son  :public  Base<int >{ }; void  test01 ()  {	Son s1; } template <class  T1 ,class  T2 >class  Son2  :public  Base<T2>{ public :	Son2() 	{ 		cout  << typeid (T1).name()<< endl ; 		cout  << typeid (T2).name()<< endl ; 	} 	T1 obj; }; void  test02 ()  {	Son2<int , char >s2; } int  main (void )  {	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 : 如果父类是类模板,子类需要指定出父类中T的数据类型。
类模板成员函数类外实现 学习目标 :
能够掌握类模板中的成员函数类外实现 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream>  #include <string>  using  namespace  std ;template <class  T1 ,class  T2  >class  Person { public :	Person(T1 name, T2 age); 	void  showPerson ()  ; 	T1 m_Name; 	T2 m_Age; }; template <class  T1 ,class  T2 >Person<T1,T2>::Person(T1 name, T2 age) { 	this ->m_Name = name; 	this ->m_Age = age; } template <class  T1 ,class  T2 >void  Person<T1,T2>::showPerson(){ 	cout  << this ->m_Name << this ->m_Age << endl ; } void  test01 ()  {	Person<string , int >p1("新二" , 13 ); 	p1.showPerson(); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
类模板中成员函数类外实现时,需要加上模板参数列表。
类模板分文件编写 学习目标 :
掌握类模板成员函数分文件编写产生的问题以及解决方式
问题 :类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到 
解决 :
解决方式1:直接包含.cpp源文件 
解决方式2:将声明.h和实现.cpp在到同一个文件中,并更改后缀名为.hpp,hpp是约定俗成的名称,并不是强制 
 
.hpp文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #pragma  once #include <iostream>  using  namespace  std ;template <class  T1 , class  T2 >class  Person { public :	Person(T1 name, T2 age); 	void  showPerson ()  ; 	T1 m_Name; 	T2 m_Age; }; template <class  T1 , class  T2 >Person<T1, T2>::Person(T1 name, T2 age) { 	this ->m_Name = name; 	this ->m_Age = age; } template <class  T1 , class  T2 >void  Person<T1, T2>::showPerson(){ 	cout  << this ->m_Name << this ->m_Age << endl ; } 
 
.cpp文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream>  #include "Person.hpp"  using  namespace  std ;#include <string>  void  test01 ()  {	Person<string , int >p1("伞兵" , 18 ); 	p1.showPerson(); } int  main (void )  {	test01(); 	system("pause" );  	return  0 ; } 
 
总结 :
主流的解决方式是第二种,将类模板成员函数写到一起,并将后缀名改为.hpp
类模板与友元 学习目标 : 掌握类模板配合友元函数的类内和类外实现
全局函数类内实现,直接在类内声明友元即可、
全局函数类外实现,需要提前让编译器知道全局函数的存在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <iostream>  #include <string>  using  namespace  std ;template <class  T1 , class  T2  >class  Person ;template <class  T1 , class  T2 >void  PrintPerosn2 (Person<T1, T2>p)  {	cout  << "类外实现"  << p.m_Name << p.m_Age < endl ; } template <class  T1 ,class  T2  >class  Person { 	 	friend  void  PrintPerosn (Person<T1,T2>p)  	 {		cout  << p.m_Name << p.m_Age << endl ; 	} 	 	 	 	friend  void  PrintPerosn2<>(Person<T1, T2>p); public :	Person(T1 name,T2 age) 	{ 		this ->m_Name = name; 		this ->m_Age = age; 		 	} private :	T1 m_Name; 	T2 m_Age; }; void  test01 ()  {	Person<string , int >p("zbc" , 12 ); 	PrintPerosn(p); } void  test02 ()  {	Person<string , int >p2("年轻人" , 18 ); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
建议全局函数做类内实现,用法简单,而且编译器可以直接识别。
类模板案例 案例描述 :
可以对内置数据类型以及自定义数据类型的数据进行存储 
将数组中的数据存储到堆区 
构造函数中可以传入数组的容量 
提供对应的拷贝构造函数以及operator=防止浅拷贝问题 
提供尾插法和尾删法对数组中的数据进行增加和删除 
可以通过下标的方式访问数组中的元素 
可以获取数组汇中当前元素个数和数组的容量 
 
MyArry.hpp中代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 #pragma  once  #include <iostream>  using  namespace  std ;template <class  T >class  MyArry { public :	 	MyArry(int  capacity) 	{ 		 		this ->m_Capacity = capacity; 		this ->m_Size = 0 ; 		this ->pAddress = new  T[this ->m_Capacity]; 	} 	 	MyArry(const  MyArry& arr) 	{ 		 		this ->m_Capacity = arr.m_Capacity; 		this ->m_Size = arr.m_Size; 		 		 		this ->pAddress = new  T[arr.m_Capacity]; 		 		 		for  (int  i = 0 ; i < this ->m_Size; i++) 		{ 			this ->pAddress[i] = arr.pAddress[i]; 		} 	} 	 	MyArry& operator  =(const  MyArry& arr) 	{ 		 		 		if  (this ->pAddress != NULL ) 		{ 			delete [] this ->pAddress; 			this ->pAddress = NULL ; 			this ->m_Capacity = 0 ; 			this ->m_Size = 0 ; 		} 		 		this ->m_Capacity = arr.m_Capacity; 		this ->m_Size = arr.m_Size; 		this ->pAddress = new  T[arr.m_Capacity]; 		for  (int  i = 0 ; i < this ->m_Size; i++) 		{ 			this ->pAddress[i] = arr.pAddress[i]; 		} 		return  *this ; 	} 	 	void  PushBack (const  T& val)  	 {		 		if  (this ->m_Capacity == this ->m_Size) 		{ 			return ; 		} 		this ->pAddress[this ->m_Size] = val; 		this ->m_Size++; 	} 	 	void  PopBack ()  	 {		 		if  (this ->m_Size == 0 ) 		{ 			return ; 		} 		this ->m_Size--; 	} 	 	T& operator [](int  index) 	{ 		return  this ->pAddress[index]; 	} 	 	int  getCapacity ()  	 {		return  this ->m_Capacity; 	} 	 	int  getSize ()  	 {		return  this ->m_Size; 	} 	 	~MyArry() 	{	 		if  (this ->pAddress != NULL ) 		{ 			 			delete [] this ->pAddress; 			this ->pAddress = NULL ; 		} 	} private :	T* pAddress; 	int  m_Capacity; 	int  m_Size; }; 
 
  test.cpp中代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 #include <iostream>  #include "MyArray.hpp"  #include <string>  using  namespace  std ;void  PrintArry (MyArry <int > &arr)  {	for  (int  i = 0 ; i < arr.getSize(); i++) 	{ 		cout  << arr[i] << endl ; 	} } void  test01 ()  {	MyArry <int >arr1(5 ); 	for  (int  i = 0 ; i < 5 ; i++) 	{ 		 		arr1.PushBack(i); 	} 	cout  << "arr1的打印输出"  << endl ; 	PrintArry(arr1); 	cout  << "arr1的容量为"  << arr1.getCapacity() << endl ; 	cout  << "arr1的大小为"  << arr1.getSize() << endl ; 	 	 	cout  << "arr2的打印输出"  << endl ; 	MyArry <int >arr2(arr1); 	PrintArry(arr2); 	 	arr2.PopBack(); 	cout  << "arr2尾删后"  << endl ; 	cout  << "arr2的容量为"  << arr2.getCapacity() << endl ; 	cout  << "arr2的大小为"  << arr2.getSize() << endl ; 	 } class  Person { public :	Person(){}; 	Person(string  name,int  age) 	{ 		this ->m_Name = name; 		this ->m_Age = age; 	} 	string  m_Name; 	int  m_Age; }; void  PrintPersonArry (MyArry<Person>& arr)  {	for  (int  i = 0 ; i < arr.getSize(); i++) 	{ 		cout  << "姓名"  << arr[i].m_Name << "年龄"  << arr[i].m_Age << endl ; 	} } void  test02 ()  {	MyArry<Person>arr(10 ); 	Person p1 ("伞兵1" , 21 )  ; 	Person p2 ("伞兵2" , 22 )  ; 	Person p3 ("伞兵3" , 23 )  ; 	Person p4 ("伞兵4" , 24 )  ; 	Person p5 ("伞兵5" , 25 )  ; 	 	arr.PushBack(p1); 	arr.PushBack(p2); 	arr.PushBack(p3); 	arr.PushBack(p4); 	arr.PushBack(p5); 	 	PrintPersonArry(arr); 	 	cout  << "arr容量为"  << arr.getCapacity() << endl ; 	 	cout  << "arr大小为"  << arr.getSize() << endl ; } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 : 能够利用所学知识点实现通用的数组。
STL初识 STL的诞生 
长久以来,软件届就一直希望建立一种可重复利用的东西 
C++的面向对象和泛型编程思想,目的就是复用性的提升 
大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作 
为了建立数据结构和算法的一套标准,诞生了STL 
 
STL基本概念 
STL(Standard Template Library,标准模板库) 
STL从广义上分为:容器(container)算法(algorithm)迭代器(iterator) 
容器和算法之间通过迭代器进行无缝连接 
STL几乎所有的代码都采用了模板类或者模板函数 
 
STL六大组建  STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器。
容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。 
算法:常用的各种算法,如sort、find、copy、for_each等 
迭代器:扮演了容器与算法之间的胶合剂 
仿函数:行为类似函数,可作为算法的某种策略 
适配器:一种用来修饰容器或者仿函数或迭代器结构的东西。 
空间配置器:负责空间的配置与管理。 
 
STL中容器、算法、迭代器 容器 :置物之所也
STL容器就是将运用最广泛的一些数据结构实现出来
常用的数据结构:数组、链表、树、栈、队列、集合、映射表等
这些容器分为序列式容器和关联式容器
    序列式容器 :强调值的排序,序列式容器中的每个元素均有固定的位置
    关联式容器 :二叉树结构体,各元素之间没有严格上的物理上的顺序关系
算法 :问题之解法也
有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms)
算法分为:质变算法和非质变算法
质变算法:是指运算过程中会更改区间内元素的内容。例如拷贝、查找、删除等等
非质变算法:是指在运算过程中不会更改区间内的元素内容,例如查找、
计数、遍历、寻找极值等等
迭代器 :容器和算法之间的的粘合剂
提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。
每个容器都有自己专属的迭代器。
迭代器的使用非常类似于指针,初学阶段我们可以先理解迭代器为指针。
迭代器种类:
常用的容器中迭代器种类为双向迭代器,和随机访问迭代器。
容器算法迭代器初识 了解STL容器、算法、迭代器概念之后,我们利用代码感受STL的魅力
STL中最常用的容器为Vector,可以理解为数组,下面我们将学习如何向这个容器中插入数据、并遍历这个容器
Vector存放内置数据类型 容器:vector
算法:for_each
迭代器:vector::iterator 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <iostream>  #include <vector>  #include <algorithm>//标准算法的头文件  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << endl ; } void  test01 ()  {	 	vector <int >v; 	 	v.push_back(10 ); 	v.push_back(20 ); 	v.push_back(30 ); 	v.push_back(40 ); 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	for_each(v.begin(), v.end(), myPrint); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
Vector存放自定义数据类型 学习目标 :vector中存放自定义数据类型,并打印输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream>  #include <vector>  #include <string>  #include <algorithm>//标准算法的头文件  using  namespace  std ;class  Person { public :	Person(string  name,int  age ) 	{ 		this ->m_Age = age; 		this ->m_Name = name; 	} 	string  m_Name; 	int  m_Age;  }; void  test01 ()  {	vector <Person>v; 	Person p1 ("a1" , 10 )  ; 	Person p2 ("a2" , 10 )  ; 	Person p3 ("a3" , 10 )  ; 	Person p4 ("a4" , 10 )  ; 	Person p5 ("a5" , 10 )  ; 	 	v.push_back(p1); 	v.push_back(p2); 	v.push_back(p3); 	v.push_back(p4); 	v.push_back(p5); 	 	for  (vector <Person>::iterator it = v.begin(); it != v.end(); it++) 	{ 		 		cout  << "姓名:"  << it->m_Name << "年龄:"  << it->m_Age << endl ; 	} } void  test02 ()  {	vector <Person*>v; 	Person p1 ("a1" , 10 )  ; 	Person p2 ("a2" , 10 )  ; 	Person p3 ("a3" , 10 )  ; 	Person p4 ("a4" , 10 )  ; 	Person p5 ("a5" , 10 )  ; 	 	v.push_back(&p1); 	v.push_back(&p2); 	v.push_back(&p3); 	v.push_back(&p4); 	v.push_back(&p5); 	 	for  (vector <Person*>::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << "姓名:"  << (*it)->m_Name << "年龄:"  << (*it)->m_Age << endl ; 	} } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
Vector容器嵌套容器 学习目标 :容器中嵌套容器,我们将所有数据进行遍历输出
(类似二维数组)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	vector <vector <int >>v; 	 	vector <int >v1; 	vector <int >v2; 	vector <int >v3; 	vector <int >v4; 	 	for  (int  i = 0 ; i < 4 ; i++) 	{ 		v1.push_back(i + 1 ); 		v2.push_back(i + 2 ); 		v3.push_back(i + 3 ); 		v4.push_back(i + 4 ); 	} 	 	v.push_back(v1); 	v.push_back(v2); 	v.push_back(v3); 	v.push_back(v4); 	 	for  (vector <vector <int >>::iterator it = v.begin(); it != v.end(); it++) 	{ 		for  (vector <int >::iterator vit = (*it).begin(); vit != (*it).end(); vit++) 		{ 			cout  << *vit << " " ; 		} 		cout  << endl ; 	} } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
STL常用容器 string容器 string基本概念 本质 :
string是C++风格的字符串,而string本质上是一个类 
 
string和char*区别 :
char*是一个指针 
string是一个类,类内部封装了char*,管理者个字符串,是一个char&型的容器 
 
特点 : strint类内部封装了很多成员方法
例如;查找find,拷贝copy,删除delete,替换replace,插入insert
string管理char*所分配的内存,不用但是赋值越界和取值越界等,由类内部进行负责
string构造函数 构造函数原型
string()创建一个空的字符串 
string(const char* s)使用字符串s初始化 
string(const string& str)使用一个string对象初始化另一个string对象 
string(int n,char c)使用n个字符c初始化 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	string  s1; 	const  char * str = "hellow world" ; 	string  s2 (str)  ; 	cout  << "s2:" <<s2 << endl ; 	string  s3 (s2)  ; 	cout  << "s3"  << s3 << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
string赋值操作 功能描述 ;
赋值的函数原型 :
string& operator = (const char* s)char*类型字符串 赋值给当前的字符串 
string& operator = (const string &s)把字符串s赋给当前的字符串 
string& operator = (char c)把字符赋值给当前的字符串 
string& assign(const char* s)把字符串s赋值给当前的字符串 
string& assign(const char*s,int n)把字符串s的当前n个字符赋给当前的字符串 
string& assign(const string &s)把字符串s赋给当前字符串 
string& assign(int n,char c)用n个字符c赋给当前字符串 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	string  str1; 	str1 = "hello world" ; 	cout  << "str1="  << str1 << endl ; 	string  str2; 	str2 = str1; 	cout  << "str2="  << str2 << endl ; 	 	string  str3; 	str3 = 'c' ; 	cout  << "str3="  << str3 << endl ; 	string  str4; 	str4.assign("hello c艹" ); 	cout  << "str4="  << str4 << endl ; 	string  str5; 	str5.assign("hello c++" ,5 ); 	cout  << "str5="  << str5 << endl ; 	 	string  str6; 	str6.assign(str5); 	cout  << "str6="  << str6 << endl ; 	string  str7; 	str7.assign(10 , 'w' ); 	cout  << "str7="  << str7 << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : string赋值方式很多,operator=这种方式是比较实用的。
string字符串拼接 功能描述 :
函数原型 :
string& operator+=(const char* str)重载+=操作符 
string& operator+=(const char c)重载+=操作符 
string& operator+=(const string& str)重载+=操作符 
string& append(const char* s)把字符串s连接到当前字符串结尾 
string& append(const char* s,int n)把字符串s的前n个字符连接到当前字符串的结尾 
string& append(const string &s)同operator+=(const string& str) 
string& append(const string &s,int pos,int n)把字符串s中从pos开始的n个字符连接到字符串结尾 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	string  str1 = "你" ; 	str1 += "是伞兵" ; 	cout  << "str1="  << str1<< endl ; 	str1 += '?' ; 	cout  << "str1="  << str1 << endl ; 	string  str2 = "zbc" ; 	str1 += str2; 	cout  << "str1="  << str1 << endl ; 	string  str3 = "You" ; 	str3.append(" SB" ); 	cout  << "str3="  << str3 << endl ; 	str3.append("hahaha hahaha" , 4 ); 	cout  << "str3="  << str3 << endl ; 	str3.append(str2); 	cout  << "str3="  << str3 << endl ; 	str3.append(str2, 0 , 1 ); 	cout  << "str3="  << str3 << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 字符串拼接的重载版本很多,初学阶段记住几种即可。
string查找和替换 功能描述 :
查找:查找指定位置字符串是否存在 
替换:在指定的位置替换字符串 
 
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	string  str1 = "abcdefg" ; 	 	int  pos1 = str1.find("de" ); 	cout  << "pos1="  << pos1 << endl ; 	int  pos2 = str1.find("z" ); 	cout  << "pos2="  << pos2<< endl ; 	pos1 = str1.rfind("ab" ); 	cout  << "pos1="  << pos1 << endl ;; } void  test02 ()  {	string  str2 = "abcdef" ; 	str2.replace(1 , 3 , "1111" ); 	cout  << "str2="  << str2 << endl ; } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 :
find查找是从左往右,rfind从右往左 
find找到字符串后返回查找的第一个字符位置,找不到返回1 
replace在替换时,要指定从哪个位置起,多少个字符,替换成什么样的字符串 
 
string字符串比较 功能描述 : 字符串之间的比较
比较方式 :
字符串比较是按字符的ASCII码进行对比
 
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	string  str1 = "zello" ; 	string  str2 = "hello" ; 	if  (str1.compare(str2) == 0 ) 	{ 		cout  << "相等"  << endl ; 	} 	else  if  (str1.compare(str2) > 0 ) 	{ 		cout  << "str1大"  << endl ; 	} 	else  	{ 		cout  << "str2大"  << endl ; 	} } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 字符串对比主要是用于比较两个字符串是否相等,判断谁大谁小的意义并不是很大。
string字符读取 string中单个字符存取方式有两种
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	string  str1 = "hello" ; 	 	for  (int  i = 0 ; i < str1.size(); i++) 	{ 		cout  << str1[i] << " " ; 	} 	cout  << endl ; 	 	for  (int  i = 0 ; i < str1.size(); i++) 	{ 		cout  << str1.at(i) << " " ; 	} 	cout  << endl ; 	 	str1[0 ] = 'z' ; 	cout  << str1 << endl ; 	str1.at(0 ) = 'x' ; 	cout  << str1 << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
string字符串中单个字符存取有两种方式,利用[]或at
string插入和删除 功能描述 :
对string字符串进行插入和删除字符操作。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream>  #include <string>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	string  str = "hello" ; 	 	str.insert(1 , "111" ); 	cout  << "str = "  << str << endl ; 	 	str.erase(1 ,3 ); 	cout  << "str = "  << str << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 插入和删除的起始下标都是从0开始。
string字串 功能描述 : 从字符串中获得想要的字串。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream>  #include <string>  using  namespace  std ;void  test01 ()  {	string  str = "abcdef" ; 	string  subStr = str.substr(1 , 3 ); 	cout  << "subStr="  << subStr << endl ; } void  test02 ()  {	string  email = "zhangsan@qq.com" ; 	 	int  pos = email.find("@" ); 	string  usrName = email.substr(0 , pos); 	cout  << usrName << endl ; } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 : 灵活的运用求字串功能,可以在实际开发中获取有效的信息。
vector容器 vector基本概念 功能 : vector数据结构和数组非常相似,也称为单端数组
vector与普通数组区别 :
不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展 :
并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝到新空间,释放原空间。 
 
vector构造函数 功能描述 : 创建vector容器
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream>  #include <string>  #include <algorithm>  #include <vector>  using  namespace  std ;void  printVector (vector <int >& v)  {	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	vector <int >v1; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 	} 	printVector(v1); 	 	vector <int >v2(v1.begin(), v1.end()); 	printVector(v2); 	 	 	vector <int >v3(10 , 100 ); 	printVector(v3); 	 	vector <int >v4(v3); 	printVector(v4); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : vector的多种构造方式没有可比性,灵活使用即可。
vector赋值操作 功能描述 : 给vector容器进行赋值
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream>  #include <string>  #include <algorithm>  #include <vector>  using  namespace  std ;void  PrintVector (vector <int >& v)  {	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	vector <int >v1; 	for  (int  i = 0 ; i < 10 ;i++) 	{ 		v1.push_back(i); 	} 	PrintVector(v1); 	 	vector <int >v2; 	v2 = v1; 	PrintVector(v2); 	 	vector <int >v3; 	v3.assign(v1.begin(), v1.end()); 	PrintVector(v3); 	 	vector <int >v4; 	v4.assign(10 , 100 ); 	PrintVector(v4); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : vector赋值方式比较简单,使用operator=,或者assign都可以。
vector容量和大小 功能描述 : 对vector容器的容量和大小操作
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream>  #include <string>  #include <algorithm>  #include <vector>  using  namespace  std ;void  PrintVector (vector <int >& v)  {	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	vector <int >v1; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 	} 	PrintVector(v1); 	if  (v1.empty()) 	{ 		cout  << "空"  << endl ; 	} 	else  	{ 		cout  << "不空"  << endl ; 	} 	cout  << "v1的容量="  << v1.capacity() << endl ; 	cout  << "v1的大小="  << v1.size() << endl ; 	 	 	v1.resize(15 ,100 ); 	PrintVector(v1); 	v1.resize(5 ); 	PrintVector(v1); } int  main (void )   {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
判断是否为空——empty 
返回元素个数——size 
返回容器容量——capacity 
重新指定大小——resize 
 
vector插入和删除 功能描述 : 对vector容器进行插入、删除操作
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream>  #include <vector>  #include <algorithm>  using  namespace  std ;void  PrintVector (vector <int >& v)  {	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	vector <int >v1; 	 	 	v1.push_back(10 ); 	v1.push_back(20 ); 	v1.push_back(30 ); 	v1.push_back(40 ); 	v1.push_back(50 ); 	 	 	PrintVector(v1); 	 	v1.pop_back(); 	PrintVector(v1); 	 	v1.insert(v1.begin(), 100 ); 	PrintVector(v1); 	v1.insert(v1.begin(), 2 , 1000 ); 	PrintVector(v1); 	 	v1.erase(v1.begin()); 	PrintVector(v1); 	 	 	v1.clear(); 	PrintVector(v1); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
尾插——push_back 
尾删——pop_back 
插入——insert(位置迭代器) 
删除——erase(位置迭代器) 
清空——clear 
 
vector数据存取 功能描述 : 对vector中的数据进行存取操作
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	vector <int >v1; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 	}	 	 	for  (int  i = 0 ; i < v1.size(); i++) 	{ 		cout  << v1[i] << " " ; 	} 	cout  << endl ; 	 	for  (int  i = 0 ; i < v1.size(); i++) 	{ 		cout  << v1.at(i) << " " ; 	} 	cout  << endl ; 	 	 	cout  << "第一个元素="  << v1.front() << endl ; 	 	cout  << "最后一个元素="  << v1.back()<<endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
除了用迭代器获取vector中元素,[]和at也可以 
front返回容器第一个元素 
back返回容器最后一个元素 
 
vector互换容器 功能描述 ; 实现两个容器内元素进行互换
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream>  #include <vector>  #include <algorithm>  using  namespace  std ;void  PrintVector (vector <int > &v)  {	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	vector <int >v1; 	cout  << "交换前"  << endl ; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 	} 	PrintVector(v1); 	vector <int >v2; 	for  (int  i = 10 ; i > 0 ; i--) 	{ 		v2.push_back(i); 	} 	PrintVector(v2); 	cout  << "交换后"  << endl ; 	v1.swap(v2); 	PrintVector(v1); 	PrintVector(v2); } void  test02 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10000 ; i++) 	{ 		v.push_back(i); 	} 	cout  << "容量"  << v.capacity() << endl ; 	cout  << "大小"  << v.size() << endl ; 	cout  <<  endl ; 	v.resize(3 ); 	cout  << "容量"  << v.capacity() << endl ; 	cout  << "大小"  << v.size() << endl ; 	 	vector <int >(v).swap(v); 	cout  << endl ; 	cout  << "容量"  << v.capacity() << endl ; 	cout  << "大小"  << v.size() << endl ; } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 : swap可以使两个容器互换,可以达到实用的收缩内存效果。
vector预留空间 功能描述 : 减少vector在动态内存扩容时的扩展次数
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream>  #include <vector>  #include <algorithm>  using  namespace  std ;void  test01 ()  {	vector <int >v1; 	int  num = 0 ; 	int * p = NULL ; 	for  (int  i = 0 ; i < 100000 ; i++) 	{ 		v1.push_back(i); 		 		if  (p != &v1[0 ]) 		{ 			p = &v1[0 ]; 			num++; 		} 	} 	cout  << num << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 如果数据量较大,可以一开始利用reserve预留空间。
deque容器 deque容器基本概念 功能 : 双端数组,可以对头端进行插入删除操作
deque与vector区别 :
vector对于头部的插入删除效率低,数据量越大,效率越低 
deque相对而言,对头部的插入删除速度会比vector快 
vector访问元素时的速度会比deque快,这和两者内部实现有关 
 
 
deque的内部工作原理
deque内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据。
中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间。
deque容器的迭代器也是支持随机访问的。
deque构造函数 功能描述 :
deque容器构造
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream>  #include <deque>  using  namespace  std ;void  PrintDeque (const  deque <int >& d)  {	for  (deque <int >::const_iterator it = d.begin(); it != d.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	deque <int >d1; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		d1.push_back(i); 	} 	PrintDeque(d1); 	deque <int >d2(d1.begin(), d1.end()); 	PrintDeque(d2); 	deque <int >d3(10 , 100 ); 	PrintDeque(d3); 	deque <int >d4(d3); 	PrintDeque(d4); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : deque容器和vector容器的构造方式几乎一致,灵活使用即可。
deque赋值操作 功能描述 : 给deque容器进行赋值
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream>  #include <deque>  using  namespace  std ;void  PrintDeque (const  deque <int >& d)  {	for  (deque <int >::const_iterator it = d.begin(); it != d.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	deque <int >d1; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		d1.push_back(i); 	} 	PrintDeque(d1); 	 	deque <int >d2; 	d2 = d1; 	PrintDeque(d2); 	 	deque <int >d3; 	d3.assign(d1.begin(),d1.end()); 	PrintDeque(d3); 	deque <int >d4; 	d4.assign(10 , 100 ); 	PrintDeque(d4); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : deque赋值操作也与vector相同,需熟练掌握。
deque大小操作 功能描述 : 对deque容器的大小进行操作
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <iostream>  #include <deque>  using  namespace  std ;void  PrintDeque (const  deque <int >& d)  {	for  (deque <int >::const_iterator it = d.begin(); it != d.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	deque <int >d1; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		d1.push_back(i); 	} 	PrintDeque(d1); 	if  (d1.empty()) 	{ 		cout <<"空" <<endl ; 	} 	else  	{ 		cout <<"不空" <<endl ; 	} 	 	cout  << "大小"  << d1.size() << endl ; 	 	d1.resize(15 ,1 ); 	PrintDeque(d1); 	d1.resize(5 ); 	PrintDeque(d1); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
deque没有容量概念 
判断是否为空——empty 
返回元素个数——size 
重新指定个数——resize 
 
deque插入和删除 功能描述 : 向deque容器中插入和删除数据
函数原型 : 两端插入操作:
指定位置操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #include <iostream>  #include <deque>  using  namespace  std ;void  PrintDeque (const  deque <int >& d)  {	for  (deque <int >::const_iterator it = d.begin(); it != d.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	deque <int >d1; 	 	d1.push_back(10 ); 	d1.push_back(20 ); 	 	d1.push_front(100 ); 	d1.push_front(200 ); 	PrintDeque(d1); 	 	d1.pop_back(); 	PrintDeque(d1); 	 	d1.pop_front(); 	PrintDeque(d1); } void  test02 ()  {	deque <int >d2; 	 	d2.push_back(10 ); 	d2.push_back(20 ); 	 	d2.push_front(100 ); 	d2.push_front(200 ); 	PrintDeque(d2); 	 	d2.insert(d2.begin(), 1000 ); 	PrintDeque(d2); 	d2.insert(d2.begin(), 2 ,10000 ); 	PrintDeque(d2); 	 	deque <int >d3; 	d3.push_back(1 ); 	d3.push_back(2 ); 	d3.push_back(3 ); 	d2.insert(d2.begin(), d3.begin(), d3.end()); 	PrintDeque(d2); } void  test03 ()  {	deque <int >d4; 	 	d4.push_back(10 ); 	d4.push_back(20 ); 	 	d4.push_front(100 ); 	d4.push_front(200 ); 	PrintDeque(d4); 	 	deque <int >::iterator it = d4.begin(); 	it++; 	d4.erase(it); 	PrintDeque(d4); 	 	 	d4.erase(d4.begin(), d4.end()); 	PrintDeque(d4); 	 	d4.clear(); 	PrintDeque(d4); } int  main (void )  {	test01(); 	test02(); 	test03(); 	system("pause" ); 	return  0 ; } 
 
总结 :
插入和删除提供的位置是迭代器! 
尾插——push_back 
尾删——pop_back 
头插——push_front 
头删——pop_front 
 
deque数据存取 功能描述 : 对deque中的数据的存取操作
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream>  #include <deque>  using  namespace  std ;void  PrintDeque (const  deque <int >& d)  {	for  (deque <int >::const_iterator it = d.begin(); it != d.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	deque <int >d1; 	for  (int  i = 0 ; i < 3 ; i++) 	{ 		d1.push_back(i); 	} 	d1.push_front(100 ); 	d1.push_front(200 ); 	d1.push_front(300 ); 	 	 	for  (int  i = 0 ; i < d1.size(); i++) 	{ 		cout  << d1[i] << " " ; 	} 	cout  << endl ; 	 	for  (int  i = 0 ; i < d1.size(); i++) 	{ 		cout  << d1.at(i) << " " ; 	} 	cout  << endl ; 	cout  << "第一个元素="  << d1.front() << endl ; 	cout  << "最后一个元素="  << d1.back() << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
除了用迭代器获取deque容器中元素 
front返回容器第一个元素 
back返回容器最后一个元素 
 
deque排序 功能描述 : 利用算法实现对deque容器进行排序
算法 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream>  #include <deque>  #include <algorithm>//标准算法头文件  using  namespace  std ;void  PrintDeque (const  deque <int >& d)  {	for  (deque <int >::const_iterator it = d.begin(); it != d.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	deque <int >d1; 	d1.push_back(10 ); 	d1.push_back(20 ); 	d1.push_back(30 ); 	d1.push_front(100 ); 	d1.push_front(200 ); 	d1.push_front(300 ); 	PrintDeque(d1); 	 	 	 	 	cout  << "排序后"  << endl ; 	sort(d1.begin(), d1.end()); 	PrintDeque(d1); 	 } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
案例——评委打分 案例描述 有五名选手,选手ABCDE,10个评委分别对每一个选手打分,去除最高分和最低分,取平均分。
实现步骤 
创建五名选手,放到vector中 
遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque容器中 
sort算法对deque容器中分数排序,去除最高分和最低分 
deque容器遍历一遍,累加总分 
获取平均分 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 #include <iostream>  #include <string>  #include <vector>  #include <deque>  #include <algorithm>  #include <ctime>  using  namespace  std ;class  Person { public :	Person(string  name, int  score) 	{ 		this ->m_Name = name; 		this ->m_Score = score; 	} 	string  m_Name; 	int  m_Score; }; void  CreatPerson (vector <Person>& v)  {	string  nameSeed = "ABCDE" ; 	for  (int  i = 0 ; i < 5 ; i++) 	{ 		string  name = "选手" ; 		name += nameSeed[i]; 		 		int  score = 0 ; 		Person p (name, score)  ; 		v.push_back(p); 	} } void  setScroe (vector <Person>& v)  {	for  (vector <Person>::iterator it = v.begin(); it != v.end(); it++) 	{ 		 		deque <int >d; 		for  (int  i = 0 ; i < 10 ; i++) 		{ 			int  score = rand() % 41  + 60 ; 			d.push_back(score); 		} 		 		 		sort(d.begin(), d.end()); 		 		d.pop_front(); 		d.pop_back(); 		 		int  sum = 0 ; 		for  (deque <int >::iterator dit = d.begin(); dit != d.end(); dit++) 		{ 			sum += *dit; 		} 		int  avg = sum / d.size(); 		 		it->m_Score = avg; 	} } void  showScore (vector <Person>& v)  {	for  (vector <Person>::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << "姓名:"  << it->m_Name << "得分:"  << it->m_Score << endl ; 	} } int  main (void )  {	 	srand((unsigned  int )time(NULL )); 	 	vector <Person>v; 	CreatPerson(v); 	 	 	 	 	setScroe(v); 	 	showScore(v); 	system("pause" ); 	return  0 ; } 
 
stack容器 stack基本概念 概念 : stack是一种先进后出的数据结构,它只有一个出口。
栈中只有栈顶的元素才可以被外界使用,因此栈不允许有遍历行为。
栈可以判断容器是否为空。
栈可以返回元素个数。
栈中进入数据——进栈。
栈中弹出数据——出栈。
stack常用接口 功能描述 :
栈容器常用的对外接口。
构造函数 :
赋值操作 :
数据存取 :
大小操作 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream>  #include <stack>  using  namespace  std ;void  test01 ()  {	stack <int >s; 	 	s.push(1 ); 	s.push(2 ); 	s.push(3 ); 	s.push(4 ); 	cout  << "栈的大小:"  << s.size() << endl ; 	 	while  (!s.empty()) 	{ 		cout  << s.top() << endl ; 		s.pop(); 	} 	cout  << "栈的大小:"  << s.size()<< endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
入栈——push 
出栈——pop 
返回栈顶——top 
判断栈是否为空——empty 
返回栈大小——size 
 
queue容器 queue容器基本概念 概念 : Queue是一种先进先出的数据结构,它有两个出口。
只有队头和队尾能被外界访问,因此不允许有遍历行为。
队列容器允许从一端新增元素,从另一端移除元素。
队列中进入数据——入队。
队列中出数据——出队。
queue常用接口 功能描述 : 栈容器常用的对外接口。
构造函数 :
赋值操作 :
数据存取 :
大小操作 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream>  #include <queue>  #include <string>  using  namespace  std ;class  Person { public :	Person(string  name, int  age) 	{ 		this ->m_Name = name; 		this ->m_Age = age; 	} 	string  m_Name; 	int  m_Age; }; void  test01 ()  {	queue <Person>q; 	Person p1 ("s1" , 1 )  ; 	Person p2 ("s2" , 2 )  ; 	Person p3 ("s3" , 3 )  ; 	Person p4 ("s4" , 4 )  ; 	q.push(p1); 	q.push(p2); 	q.push(p3); 	q.push(p4); 	cout  << "大小="  << q.size() << endl ; 	while  (!q.empty()) 	{ 		cout  << q.front().m_Name <<" "  << q.front().m_Age << endl ; 		q.pop(); 	} 	cout  << "大小="  << q.size() << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
入队——push 
出队——pop 
返回队头元素——front 
返回队尾元素——back 
判断队是否为空——empty 
返回队列大小——size 
 
list容器 list基本概念 功能 :将数据进行链式存储
**链表(list)**:是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接来实现的。
链表的组成:链表由一系列结点组成。
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
SLT中的链表是一个双向循环链表。
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器。
list的优点:
采用动态存储分配,不会造成内存浪费和溢出 
链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素 
 
list的缺点:
链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大。
list有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。
总结 : STL中List和vector是两个最常用的容器,各有优缺点。
list构造函数 功能描述 : 创建list容器
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream>  #include <list>  using  namespace  std ;void  PrintList (const  list <int >& L)  {	for  (list <int >::const_iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	list <int >l1; 	l1.push_back(1 ); 	l1.push_back(2 ); 	l1.push_back(3 ); 	l1.push_back(4 ); 	PrintList(l1); 	list <int >l2(l1.begin(), l1.end()); 	PrintList(l2); 	list <int >l3(l2); 	PrintList(l3); 	 	list <int >l4(10 , 100 ); 	PrintList(l4); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
list构造方式同其他几个STL常用容器,熟练掌握即可。
list赋值和交换 功能描述 : 给list容器进行赋值,以及交换list容器。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64  #include <iostream>   #include <list>  using  namespace  std ;void  PrintList (const  list <int >& L)  {	for  (list <int >::const_iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	list <int >l1; 	l1.push_back(1 ); 	l1.push_back(2 ); 	l1.push_back(3 ); 	l1.push_back(4 ); 	PrintList(l1); 	list <int >l2; 	l2 = l1; 	PrintList(l2); 	list <int >l3; 	l3.assign(l2.begin(), l2.end()); 	PrintList(l3); 	list <int >l4; 	l4.assign(10 , 100 ); 	PrintList(l4); } void  test02 ()  {	list <int >l5; 	l5.push_back(1 ); 	l5.push_back(2 ); 	l5.push_back(3 ); 	l5.push_back(4 ); 	list <int >l6; 	l6.push_back(4 ); 	l6.push_back(3 ); 	l6.push_back(2 ); 	l6.push_back(1 ); 	cout  << "交换前"  << endl ; 	PrintList(l5); 	PrintList(l6); 	l5.swap(l6); 	cout  << "交换后"  << endl ; 	PrintList(l5); 	PrintList(l6); } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 : list赋值和交换能够灵活运用即可。
list大小操作 功能描述 : 对list容器的大小进行操作。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream>  #include <list>  using  namespace  std ;void  PrintList (const  list <int >& L)  {	for  (list <int >::const_iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	list <int >l1; 	l1.push_back(1 ); 	l1.push_back(2 ); 	l1.push_back(3 ); 	l1.push_back(4 ); 	 	PrintList(l1); 	if  (l1.empty()) 	{ 		cout  << "空"  << endl ; 	} 	else  	{ 		cout  << "不空"  << endl ; 		cout  << "元素个数="  << l1.size()<<endl ; 	} 	 	 	l1.resize(10 , 1000 ); 	PrintList(l1); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
判断是否为空——empty 
返回元素个数——size 
重新指定个数——resize 
 
list插入和删除 功能描述 : 对list容器进行数据的插入和删除
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <iostream>  #include <list>  using  namespace  std ;void  PrintList (const  list <int >& L)  {	for  (list <int >::const_iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	list <int >l1; 	 	l1.push_back(1 ); 	l1.push_back(2 ); 	l1.push_back(3 ); 	l1.push_back(4 ); 	 	l1.push_front(10 ); 	l1.push_front(20 ); 	PrintList(l1); 	 	l1.pop_back(); 	PrintList(l1); 	l1.pop_front(); 	PrintList(l1); 	 	list <int >::iterator it = l1.begin(); 	it++; 	l1.insert(it, 1000 ); 	PrintList(l1); 	 	 	it = l1.begin(); 	l1.erase(++it); 	PrintList(l1); 	 	l1.push_back(1000 ); 	l1.push_back(1000 ); 	l1.push_back(1000 ); 	PrintList(l1); 	l1.remove(1000 ); 	PrintList(l1); 	 	l1.clear(); 	PrintList(l1); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
尾插——push_back 
尾删——pop_back 
头插——push_front 
头删——pop_front 
插入——insert 
删除——erase 
移除——remove 
清空——clear 
 
list数据存取 功能描述 : 对list容器中数据进行存储。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream>  #include <list>  using  namespace  std ;void  PrintList (const  list <int >& L)  {	for  (list <int >::const_iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	list <int >l1; 	l1.push_back(1 ); 	l1.push_back(2 ); 	l1.push_back(3 ); 	l1.push_back(4 ); 	 	 	 	cout  << "第一个元素="  << l1.front() << endl ; 	cout  << "最后一个元素="  << l1.back() << endl ; 	 	list <int >::iterator it = l1.begin(); 	it++; 	it--; 	 } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
list容器中不可以通过[]或者at方式访问数据 
返回第一个元素——front 
返回最后一个元素——back 
 
list反转和排序 功能描述 : 将容器中的元素反转,以及将容器中的数据进行排序。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #include <iostream>  #include <list>  #include <algorithm>  using  namespace  std ;void  PrintList (const  list <int >& L)  {	for  (list <int >::const_iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	list <int >l1; 	l1.push_back(1 ); 	l1.push_back(2 ); 	l1.push_back(3 ); 	l1.push_back(4 ); 	 	cout  << "反转前"  << endl ; 	PrintList(l1); 	 	cout  << "反转后"  << endl ; 	l1.reverse(); 	PrintList(l1); } bool  myCompare (int  v1, int  v2)  {	 	return  v1 > v2; } void  test02 ()  {	list <int >l2; 	l2.push_back(20 ); 	l2.push_back(10 ); 	l2.push_back(50 ); 	l2.push_back(30 ); 	l2.push_back(40 ); 	cout  << "排序前"  << endl ; 	PrintList(l2); 	 	 	cout  << "排序后"  << endl ; 	l2.sort(); 	PrintList(l2); 	l2.sort(myCompare); 	PrintList(l2); } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 :
反转——reverse 
排序——sort(成员函数) 
 
排序案例 案例描述 :将Person自定义类型进行排序,Person中属性有姓名、年龄、身高。
排序规则 :按照年龄进行升序,如果年龄相同则按照身高进行降序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <iostream>  #include <list>  #include <string>  using  namespace  std ;class  Person { public :	Person(string  name, int  age, int  height) 	{ 		this ->m_Age = age; 		this ->m_Height = height; 		this ->m_Name = name; 	} 	string  m_Name; 	int  m_Age; 	int  m_Height; }; bool  comparePerson (Person &p1,Person &p2)  {	 	if  (p1.m_Age == p2.m_Age) 	{ 		 		return  p1.m_Height > p2.m_Height; 	} 	else  	{ 		return  p1.m_Age < p2.m_Age; 	} 	 } void  test01 ()  {	list <Person>L; 	Person p1 ("s11" ,23 ,166 )  ; 	Person p2 ("s12" ,23 ,156 )  ; 	Person p3 ("s13" ,23 ,178 )  ; 	Person p4 ("s14" ,33 ,172 )  ; 	Person p5 ("s15" ,43 ,190 )  ; 	Person p6 ("s16" ,45 ,175 )  ; 	L.push_back(p1); 	L.push_back(p2); 	L.push_back(p3); 	L.push_back(p4); 	L.push_back(p5); 	L.push_back(p6); 	for  (list <Person>::iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << it->m_Name <<" "  << it->m_Age <<" " << it->m_Height << endl ; 	} 	cout  << "排序后"  << endl ; 	L.sort(comparePerson); 	for  (list <Person>::iterator it = L.begin(); it != L.end(); it++) 	{ 		cout  << it->m_Name << " "  << it->m_Age << " "  << it->m_Height << endl ; 	} } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序 
高级排序只是在排序规则上再进行一次逻辑规则制定,并不复杂。 
 
set/multiset容器 set基本概念 简介 : 所有元素都会在插入时被自动排序。
本质 : set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别 :
set不允许容器中有重复的元素。 
multiset允许容器中有重复的元素 
 
set构建和赋值 功能描述 :
创建set容器以及赋值。
构造 :
赋值 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream>  #include <set>  using  namespace  std ;void  PrintSet (set <int > &s)  {	for  (set <int >::iterator it = s.begin(); it != s.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	set <int >s1; 	 	s1.insert(30 ); 	s1.insert(20 ); 	s1.insert(10 ); 	s1.insert(40 ); 	PrintSet(s1); 	set <int >s2(s1); 	PrintSet(s2); 	set <int >s3; 	s3 = s2; 	PrintSet(s3); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
set容器插入数据时用insert 
set容器插入的数据会自动排序 
 
set大小和交换 功能描述 : 统计set容器大小以及交换set容器。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 #include <iostream>  #include <set>  using  namespace  std ;void  PrintSet (set <int > &s)  {for  (set <int >::iterator it = s.begin(); it != s.end(); it++){ 	cout  << *it << " " ; } cout  << endl ;} void  test01 ()  {	set <int >s1; 	s1.insert(10 ); 	s1.insert(20 ); 	s1.insert(30 ); 	s1.insert(40 ); 	PrintSet(s1); 	 	if  (s1.empty()) 	{ 		cout  << "空"  << endl ; 	} 	else  	{ 		cout  << "不空"  << endl ; 		cout  << "大小:"  << s1.size() << endl ; 	} 	 } void  test02 ()  {	set <int >s2; 	set <int >s3; 	s2.insert(100 ); 	s2.insert(200 ); 	s2.insert(300 ); 	s3.insert(1 ); 	s3.insert(2 ); 	s3.insert(3 ); 	 	cout  << "交换前:"  << endl ; 	PrintSet(s2); 	PrintSet(s3); 	s2.swap(s3); 	cout  << "交换后:"  << endl ; 	PrintSet(s2); 	PrintSet(s3); } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 :
统计大小——size 
判断是否为空——empty 
交换容器——swap 
 
set插入和删除 功能描述 : set容器进行插入数据和删除数据
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <iostream>  #include <set>  using  namespace  std ;void  PrintSet (set <int > &s)  {for  (set <int >::iterator it = s.begin(); it != s.end(); it++){ 	cout  << *it << " " ; } cout  << endl ;} void  test01 ()  {	set <int >s1; 	 	s1.insert(2 ); 	s1.insert(1 ); 	s1.insert(3 ); 	s1.insert(4 ); 	PrintSet(s1); 	s1.erase(s1.begin()); 	PrintSet(s1); 	s1.erase(3 ); 	PrintSet(s1); 	 	s1.erase(s1.begin(), s1.end()); 	PrintSet(s1); 	s1.clear(); 	PrintSet(s1); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
插入——insert 
删除——erase 
清空——clear 
 
ser查找和统计 功能描述 : 对set容器进行查找数据以及统计数据
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream>  #include <set>  using  namespace  std ;void  PrintSet (set <int > &s)  {for  (set <int >::iterator it = s.begin(); it != s.end(); it++){ 	cout  << *it << " " ; } cout  << endl ;} void  test01 ()  {	set <int >s1; 	s1.insert(1 ); 	s1.insert(2 ); 	s1.insert(3 ); 	s1.insert(4 ); 	set <int >::iterator pos = s1.find(3 ); 	if  (pos != s1.end()) 	{ 		cout  << "找到"  << *pos << endl ; 	} 	else  	{ 		cout  << "没找到"  << endl ; 	} 	int  num = s1.count(3 ); 	 	cout  << num << "个"  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
查找——find(返回的是迭代器) 
统计——count(对于set,结果为0或者1) 
 
set和multiset区别 学习目标 : 掌握set和multiset的区别
区别 :
set不可以插入重复数据,而multiset可以 
set插入数据的同时会返回插入结果,表示插入是否成功 
multiset不会检测数据,因此可以插入重复数据 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <iostream>  #include <set>  using  namespace  std ;void  PrintMultiSet (multiset <int >& ms)  {	for  (multiset <int >::iterator it = ms.begin(); it != ms.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } void  test01 ()  {	set <int >s1; 	pair <set <int >::iterator,bool >ret = s1.insert(10 ); 	 	if  (ret.second) 	{ 		cout  << "插入成功"  << endl ; 	} 	else  	{ 		cout  << "插入失败"  << endl ; 	} 	 	ret = s1.insert(10 ); 	if  (ret.second) 	{ 		cout  << "插入成功"  << endl ; 	} 	else  	{ 		cout  << "插入失败"  << endl ; 	} 	multiset <int >ms; 	ms.insert(10 ); 	ms.insert(10 ); 	PrintMultiSet(ms); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
如果不允许插入重复数据可以利用set 
如果需要插入重复数据利用multiset 
 
pair对组创建 功能描述 : 成对出现的数据,利用对组可以返回两个数据。
两种创建方式 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream>  #include <string>  using  namespace  std ;void  test01 ()  {	 	pair <string , int >p("Tom" , 11 ); 	cout  << p.first <<" " << p.second << endl ; 	 	pair <string , int >p2 = make_pair ("Jerry" , 12 ); 	cout  << p2.first << " "  << p2.second << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 两种方式都可以创建对组,记住一种即可。
set容器排序 学习目标 : set容器默认排序规则为从小到大,掌握如何改变排序规则。
主要技术点 : 利用仿函数,可以改变排序顺序。
内置类型 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream>  #include <set>  using  namespace  std ;class  MyCompare { public :	 	bool  operator () (int  v1,int  v2) const  	 {		return  v1 > v2;  	} }; void  test01 ()  {	set <int ,MyCompare>s1; 	 	s1.insert(10 ); 	s1.insert(20 ); 	s1.insert(30 ); 	s1.insert(40 ); 	for  (set <int ,MyCompare>::iterator it = s1.begin(); it != s1.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
自定义类型 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <iostream>  #include <set>  #include <string>  using  namespace  std ;class  Person { public :	Person(string  name, int  age) 	{ 		this ->m_Age = age; 		this ->m_Name = name; 	} 	string  m_Name; 	int  m_Age; }; class  Mycompare { public :	bool  operator () (const  Person& p1, const  Person& p2) const  	 {		return  p1.m_Age > p2.m_Age; 	} }; void  test01 ()  {	set <Person, Mycompare>s1; 	Person p1 ("s1" ,11 )  ; 	Person p2 ("s2" ,22 )  ; 	Person p3 ("s3" ,33 )  ; 	Person p4 ("s4" ,44 )  ; 	s1.insert(p1); 	s1.insert(p2); 	s1.insert(p3); 	s1.insert(p4); 	for  (set <Person, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++) 	{ 		cout  << it->m_Name << " "  << it->m_Age << endl ; 	} } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
map/multimap容器 map基本概念 简介 :
map中所有元素都是pair 
pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值) 
所有元素都会根据元素的键值自动排序 
 
本质 : map/multimap属于关联式容器,底层结构是用二叉树实现。
优点 :
可以根据key值快速找到value值
区别 : map和multimap区别
map不允许容器中有重复key值元素 
multimap允许容器中有重复key值元素 
 
map构造和赋值 功能描述 : 对map容器进行构造和赋值操作。
函数原型 :构造 :
赋值 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream>  #include <map>  using  namespace  std ;void  PrintMap (map <int , int >& m)  {	for  (map <int , int >::iterator it = m.begin(); it != m.end(); it++) 	{ 		cout  << "key="  << (*it).first << "value="  << (*it).second << "   "  ; 	} 	cout  << endl ; } void  test01 ()  {	map <int , int >m1; 	m1.insert(pair <int , int >(1 , 10 )); 	m1.insert(pair <int , int >(2 , 20 )); 	m1.insert(pair <int , int >(3 , 30 )); 	m1.insert(pair <int , int >(4 , 40 )); 	PrintMap(m1); 	map <int , int >m2(m1); 	PrintMap(m1); 	map <int , int >m3; 	m3 = m2; 	PrintMap(m3); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : map中所有元素都是成对出现,插入数据时要使用对组。
map大小和交换 功能描述 : 统计map容器大小以及交换map容器
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <iostream>  #include <map>  using  namespace  std ;void  PrintMap (map <int , int >& m)  {	for  (map <int , int >::iterator it = m.begin(); it != m.end(); it++) 	{ 		cout  << "key="  << (*it).first << "value="  << (*it).second << "   "  ; 	} 	cout  << endl ; } void  test01 ()  {	map <int , int >m1; 	m1.insert(pair <int , int >(1 , 10 )); 	m1.insert(pair <int , int >(2 , 20 )); 	m1.insert(pair <int , int >(3 , 30 )); 	m1.insert(pair <int , int >(4 , 40 )); 	PrintMap(m1); 	if  (m1.empty()) 	{ 		cout  << "空"  << endl ; 	} 	else  	{ 		cout  << "不空"  << endl ; 		cout  << "大小="  << m1.size() << endl ; 	} 	map <int , int >m2; 	m2.insert(pair <int , int >(10 , 1 )); 	m2.insert(pair <int , int >(20 , 2 )); 	m2.insert(pair <int , int >(30 , 3 )); 	m2.insert(pair <int , int >(40 , 4 )); 	cout  << "交换前"  << endl ; 	PrintMap(m1); 	PrintMap(m2); 	cout  << "交换后"  << endl ; 	m1.swap(m2); 	PrintMap(m1); 	PrintMap(m2); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
统计大小——size 
判断是否为空——empty 
交换容器——swap 
 
map插入和删除 功能描述 : map容器进行插入数据和删除数据
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream>  #include <map>  using  namespace  std ;void  PrintMap (map <int , int >& m)  {	for  (map <int , int >::iterator it = m.begin(); it != m.end(); it++) 	{ 		cout  << "key="  << it->first << " "  << "value="  << it->second << endl ; 	} 	cout  << endl ; } void  test01 ()  {	map <int , int >m1; 	 	m1.insert(pair <int , int >(1 , 10 )); 	 	m1.insert(make_pair (2 , 20 )); 	 	m1.insert(map <int , int >::value_type(3 , 30 )); 	 	m1[4 ] = 40 ; 	cout  << m1[4 ] << endl ; 	PrintMap(m1); 	m1.erase(m1.begin()); 	PrintMap(m1); 	 	m1.erase(3 ); 	PrintMap(m1); 	m1.erase(m1.begin(), m1.end()); 	PrintMap(m1); 	m1.clear(); 	PrintMap(m1); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
map插入方式很多,记住其一即可 
插入——insert 
删除——erase 
清空——clear 
 
map查找和统计 功能描述 : 对map容器进行查找和数据以及统计数据
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream>  #include <map>  using  namespace  std ;void  PrintMap (map <int , int >& m)  {	for  (map <int , int >::iterator it = m.begin(); it != m.end(); it++) 	{ 		cout  << "key="  << it->first << " "  << "value="  << it->second << endl ; 	} 	cout  << endl ; } void  test01 ()  {	map <int , int >m1; 	m1.insert(pair <int , int >(1 , 10 )); 	m1.insert(pair <int , int >(2 , 20 )); 	m1.insert(pair <int , int >(3 , 30 )); 	map <int , int >::iterator pos = m1.find(3 ); 	if  (pos != m1.end()) 	{ 		cout  << "找到了"  <<pos->first<<" " <<pos->second<< endl ; 	} 	else  	{ 		cout  << "没找到"  << endl ; 	} 	 	 	int  num = m1.count(3 ); 	cout  << num << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
查找——find(返回的是迭代器) 
统计——cout(对于map,结果为0或1) 
 
map容器排序 学习目标 : map容器默认排序规则为按照key值进行从小到大排序,掌握如何改变排序规则。
主要技术点 : 利用仿函数,可以改变排序规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream>  #include <map>  using  namespace  std ;class  MyCompare { public :	bool  operator () (int  v1,int  v2) const   	 {		return  v1 > v2; 	} }; void  PrintMap (map <int , int , MyCompare>& m)  {	for  (map <int , int , MyCompare>::iterator it = m.begin(); it != m.end(); it++) 	{ 		cout  << "key="  << it->first << " "  << "value="  << it->second << endl ; 	} 	cout  << endl ; } void  test01 ()  {	map <int , int ,MyCompare>m1; 	m1.insert(make_pair (1 , 10 )); 	m1.insert(make_pair (2 , 20 )); 	m1.insert(make_pair (3 , 30 )); 	m1.insert(make_pair (4 , 40 )); 	m1.insert(make_pair (5 , 50 )); 	PrintMap(m1); } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
利用仿函数可以指定map容器的排序规则 
对于自定义数据类型,map必须要指定排序规则,同set容器 
 
案例——员工分组 案例描述 
公司今天招聘了10个员工(ABCDEFGHIJ),10名员工进入公司之后,需要指派员工在哪个部门工作。 
员工信息有:姓名、工资组成、部门分为:策划、美术、研发 
通过multimap进行信息的插入 key(部门编号)value(员工) 
分部门显示员工信息 
 
实现步骤 
创建10名员工,放到vector中 
遍历vector容器,取出每个员工,进行随机分组 
分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中 
分部门显示员工信息 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 #include <iostream>  #include <map>  #include <vector>  #include <string>  #include <ctime>  using  namespace  std ;#define  CEHUA 0 #define  MEISHU 1 #define  YANFA 2 class  Worker { public :	string  m_Name; 	int  m_Salary; }; void  CreatWorker (vector <Worker> &v)  {	string  NameSeed = "ABCDEFGHIJ" ; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		Worker worker; 		worker.m_Name = "员工" ; 		worker.m_Name += NameSeed[i]; 		worker.m_Salary = rand() % 10000  + 10000 ; 		 		v.push_back(worker); 	} } void  SetGroup (vector <Worker>& v, multimap <int , Worker>& m)  {	for  (vector <Worker>::iterator it = v.begin(); it != v.end(); it++) 	{ 		 		int  deptId = rand() % 3 ; 		 		m.insert(make_pair (deptId, *it)); 	} } void  ShowWorkerByGroup (multimap <int ,Worker> &m)  {	cout  << "策划部门:"  << endl ; 	multimap <int ,Worker>::iterator pos = m.find(CEHUA); 	int  count = m.count(CEHUA); 	int  index = 0 ; 	for  (; pos != m.end() && index < count ; pos++,index++) 	{ 		cout  << "姓名:"  << pos->second.m_Name << "  工资:"  << pos->second.m_Salary << endl ; 	} 	cout  << "美术部门:"  << endl ; 	pos = m.find(MEISHU); 	count = m.count(MEISHU); 	index = 0 ; 	for  (; pos != m.end() && index < count; pos++, index++) 	{ 		cout  << "姓名:"  << pos->second.m_Name << "  工资:"  << pos->second.m_Salary << endl ; 	} 	cout  << "研发部门:"  << endl ; 	pos = m.find(YANFA); 	count = m.count(YANFA); 	index = 0 ; 	for  (; pos != m.end() && index < count; pos++, index++) 	{ 		cout  << "姓名:"  << pos->second.m_Name << "  工资:"  << pos->second.m_Salary << endl ; 	} } int  main (void )  {	srand((unsigned  int )time(NULL )); 	 	vector <Worker>vWorker; 	CreatWorker(vWorker); 	 	 	 	 	 	 	multimap <int , Worker>mWorker; 	SetGroup(vWorker, mWorker); 	 	ShowWorkerByGroup(mWorker); 	system("pause" ); 	return  0 ; } 
 
STL函数对象 函数对象 函数对象概念 概念 :
重载函数调用操作符的类,其对象也称为函数对象 
函数对象使用重载()时,行为类似函数调用,也叫仿函数 
 
本质 :
函数对象(仿函数)是一个类,不是一个函数。
函数对象使用 特点 :
函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值 
函数对象超出普通函数的概念,函数对象可以有自己的状态 
函数对象可以作为参数传递 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <iostream>  #include <string>  using  namespace  std ;class  MyAdd { public :	int  operator () (int  v1, int  v2)  	 {		return  v1 + v2; 	} }; void  test01 ()  {	MyAdd myadd; 	cout  << myadd(10 , 10 ) << endl ; } class  MyPrint { public :	MyPrint() 	{ 		this ->count = 0 ; 	} 	void  operator () (string  test)  	 {		cout  << test << endl ;  		this ->count++; 	} 	int  count; }; void  test02 ()  {	MyPrint myprint; 	myprint("hello world" ); 	myprint("hello world" ); 	myprint("hello world" ); 	myprint("hello world" ); 	myprint("hello world" ); 	myprint("hello world" ); 	cout  << "MyPrint调用次数为:"  << myprint.count << endl ; } void  doPrint (MyPrint& mp, string  test)  {	mp(test); } void  test03 ()  {	MyPrint myPrint; 	doPrint(myPrint, "hello c++" ); } int  main (void )  {	test01(); 	test02(); 	test03(); 	system("pause" ); 	return  0 ; } 
 
总结 :
仿函数写法非常灵活,可以作为参数进行传递。
谓词 谓词概念 概念 :
返回bool类型的仿函数称为谓词 
如果operator()接受一个参数,那么叫做一元谓词 
如果operator()接收两个参数,那么叫做二元谓词 
 
一元谓词 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <iostream>  #include <vector>  #include <algorithm>  using  namespace  std ;class  CreaterFive { public :	bool  operator () (int  val)  	 {		return  val > 5 ; 	} }; void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v.push_back(i); 	} 	 	 	vector <int >::iterator pos = find_if(v.begin(), v.end(), CreaterFive()); 	if  (pos == v.end()) 	{ 		cout  << "未找到"  << endl ; 	} 	else  	{ 		cout  << "找到了,大于5的数字为:"  << *pos << endl ; 	} } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 参数中只有一个的谓词,叫做一元谓词
二元谓词 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream>  #include <vector>  #include <algorithm>  using  namespace  std ;class  MyCompare { public :	bool  operator () (int  val1,int  val2)  	 {		return  val1 > val2; 	} }; void  test01 ()  {	vector <int >v; 	v.push_back(10 ); 	v.push_back(40 ); 	v.push_back(20 ); 	v.push_back(30 ); 	v.push_back(50 ); 	 	sort(v.begin(), v.end()); 	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; 	 	sort(v.begin(), v.end(),MyCompare()); 	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
参数只有两个的谓词,称为二元谓词。
内建函数对象 内建函数对象意义 概念 : STL内建了一些函数对象
分类 :
用法 :
这些仿函数所产生的对象,用法和一般函数完全相同 
使用内建函数对象,需要引入头文件#include< functional> 
 
算数仿函数 功能描述 :
实现四则运算 
其中negate是一元运算,其它都是二元运算 
 
仿函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>//内建函数对象头文件  using  namespace  std ;void  test01 ()  {	negate<int >n; 	cout  << n(50 ) << endl ; } void  test02 ()  {	 	plus<int >p; 	cout  << p(10 , 20 ) << endl ; } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 : 使用内建函数对象时,需要引入头文件#include< functional>
关系仿函数 功能描述 : 实现关系对比
仿函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;class  MyCompare { public :	bool  operator () (int  v1,int  v2)  	 {		return  v1 > v2; 	} }; void  test01 ()  {	vector <int >v; 	v.push_back(1 ); 	v.push_back(3 ); 	v.push_back(4 ); 	v.push_back(2 ); 	v.push_back(5 ); 	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; 	 	 	sort(v.begin(),v.end(), greater<int >()); 	for  (vector <int >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
关系仿函数最常用的就是greater<>大于
逻辑仿函数 功能描述 : 实现逻辑运算
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  test01 ()  {	vector <bool >v; 	v.push_back(true ); 	v.push_back(false ); 	v.push_back(true ); 	v.push_back(false ); 	for  (vector <bool >::iterator it = v.begin(); it != v.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; 	 	vector <bool >v2; 	v2.resize(v.size()); 	transform(v.begin(), v.end(), v2.begin(),logical_not<bool >()); 	for  (vector <bool >::iterator it = v2.begin(); it != v2.end(); it++) 	{ 		cout  << *it << " " ; 	} 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :  逻辑仿函数实际应用较少,了解即可。
STL常用算法 概述 :
算法主要是由头文件< algorithm >< functional > < numeric >组成 
< algorithm >是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历操作、复制、修改等等。 
< functional >定义了一些模板类,用以声明函数对象 
< numeric >体积很小,只包括几个在序列上面进行简单数据运算的模板函数 
 
常用遍历算法 学习目标 : 掌握常用的遍历算法
算法简写 :
for_each 功能描述 : 实现遍历容器
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  Print01 (int  val)  {	cout  << val<<" " ; } class  Print02 { public :	void  operator () (int  val)  	 {		cout  << val << " " ; 	} }; void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v.push_back(i); 	} 	for_each(v.begin(), v.end(),Print01); 	cout  << endl ; 	for_each(v.begin(), v.end(), Print02()); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : for_each在实际开发中是最常用的遍历算法,需要熟练掌握。
功能描述 :
搬运容器到另一个容器中。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;class  TransForm { public :	int  operator () (int  val)  	 {		return  val + 100 ; 	} }; class  MyPrint { public :	void  operator () (int  val)  	 {		cout  << val << " " ; 	} }; void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v.push_back(i); 	} 	vector <int >vTarget; 	vTarget.resize(v.size()); 	transform(v.begin(), v.end(), vTarget.begin(), TransForm()); 	for_each(vTarget.begin(), vTarget.end(), MyPrint()); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 搬运的目标容器必须提前开辟空间,否则无法正常搬运。
常用查找算法 学习目标 : 掌握常用的查找算法
算法简介 :
find 功能描述 : 查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  #include <string>  using  namespace  std ;class  Person { public :	Person(string  name,int  age) 	{ 		this ->m_Age = age; 		this ->m_Name = name; 	} 	 	bool  operator  ==(const  Person& p) 	{ 		if  (this ->m_Age == p.m_Age && this ->m_Name == p.m_Name) 		{ 			return  true ; 		} 		else  		{ 			return  false ; 		} 	} 	string  m_Name; 	string  m_Age; }; void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v.push_back(i); 	} 	vector <int >::iterator it = find(v.begin(), v.end(), 5 ); 	if  (it == v.end()) 	{ 		cout  << "没找到"  << endl ; 	} 	else  	{ 		cout  << "找到"  << *it << endl ; 	} } void  test02 ()  {	vector <Person>V; 	Person p1 ("1" ,11 )  ; 	Person p2 ("2" ,22 )  ; 	Person p3 ("3" ,33 )  ; 	Person p4 ("4" ,44 )  ; 	 	V.push_back(p1); 	V.push_back(p2); 	V.push_back(p3); 	V.push_back(p4); 	vector <Person>::iterator it = find(V.begin(), V.end(), p2); 	if  (it == V.end()) 	{ 		cout  << "没找到"  << endl ; 	} 	else  	{ 		cout  << "找到"  << it->m_Name << " "  << it->m_Age << endl ; 	} } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 : 利用find可以在容器中找指定的元素,返回值是迭代器。
find_if 功能描述 :
按条件查找元素。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  #include <string>  using  namespace  std ;class  GreaterFive { public :	bool  operator () (int  val)  	 {		return  val > 5 ; 	} }; void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v.push_back(i); 	} 	vector <int >::iterator it = find_if(v.begin(), v.end(), GreaterFive()); 	if  (it == v.end()) 	{ 		cout  << "没找到"  << endl ;	 	} 	else  	{ 		cout  << "找到了"  << *it << endl ; 	} } class  Person { public :	Person(string  name,int  age) 	{ 		this ->m_Age = age; 		this ->m_Name = name; 	} 	string  m_Name; 	int  m_Age; }; class  Greater20 { public :	bool  operator () (Person &p)  	 {		return  p.m_Age > 20 ; 	} }; void  test02 ()  {	vector <Person>V; 	Person p1 ("1" ,11 )  ; 	Person p2 ("2" ,22 )  ; 	Person p3 ("3" ,33 )  ; 	Person p4 ("4" ,44 )  ; 	V.push_back(p1); 	V.push_back(p2); 	V.push_back(p3); 	V.push_back(p4); 	vector <Person>::iterator it = find_if(V.begin(), V.end(), Greater20()); 	if  (it == V.end()) 	{ 		cout  << "没找到"  << endl ; 	} 	else  	{ 		cout  << "找到了"  << it->m_Name<<" " <<it->m_Age << endl ; 	} } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
adjacent_find 功能描述 : 查找相邻重复元素。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  test01 ()  {	vector <int >v; 	v.push_back(0 ); 	v.push_back(2 ); 	v.push_back(1 ); 	v.push_back(2 ); 	v.push_back(7 ); 	v.push_back(3 ); 	v.push_back(3 ); 	vector <int >::iterator it = adjacent_find(v.begin(), v.end()); 	if  (it == v.end()) 	{ 		cout  << "没找到"  << endl ; 	} 	else  	{ 		cout  << "找到相邻重复元素"  << *it << endl ; 	} } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 面试题中如果出现查找相邻重复元素,记得用STL中的adjacent_find算法
binary_search 功能描述 : 查找指定元素是否存在。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v.push_back(i); 	} 	 	bool  ret = 	binary_search(v.begin(), v.end(),9 ); 	if  (ret) 	{ 		cout  << "找到了"  << endl ; 	} 	else  	{ 		cout  << "没找到"  << endl ; 	} } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 “ 二分查找法效率很高,值得注意的是查找的容器中元素必须得是有序序列,否则结果未知。
count 功能描述 : 统计元素个数。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  #include <string>  using  namespace  std ;void  test01 ()  {	vector <int >v; 	v.push_back(10 ); 	v.push_back(10 ); 	v.push_back(40 ); 	v.push_back(20 ); 	v.push_back(30 ); 	int  num = count(v.begin(), v.end(), 10 ); 	cout  << num << endl ; } class  Person { public :	Person(string  name, int  age) 	{ 		this ->m_Age = age; 		this ->m_Name = name; 	} 	bool  operator ==(const  Person& p) 	{ 		if  (this ->m_Age == p.m_Age) 		{ 			return  true ; 		} 		else  		{ 			return  false ; 		} 	} 	string  m_Name; 	int  m_Age; }; void  test02 ()  {	vector <Person>v; 	Person p1 ("s1" ,11  )  ; 	Person p2 ("s2" ,12  )  ; 	Person p3 ("s3" ,13  )  ; 	Person p4 ("s4" ,14  )  ; 	Person p5 ("s5" ,14  )  ; 	 	v.push_back(p1); 	v.push_back(p2); 	v.push_back(p3); 	v.push_back(p4); 	v.push_back(p5); 	 	int  num = count(v.begin(), v.end(), p5); 	cout  << num << endl ; } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
总结 :
统计自定义数据类型时候,需要配合重载operator==
count_if 功能描述 : 按条件统计元素个数。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;class  Greater20 { public :	bool  operator () (int  val)  	 {		return  val > 20 ; 	} }; void  test01 ()  {	vector <int >v; 	v.push_back(10 ); 	v.push_back(20 ); 	v.push_back(40 ); 	v.push_back(30 ); 	v.push_back(50 ); 	int  num = count_if(v.begin(), v.end(), Greater20()); 	cout  << num << endl ; } class  Person { public :	Person(string  name, int  age) 	{ 		this ->m_Age = age; 		this ->m_Name = name; 	} 	string  m_Name; 	int  m_Age; }; class  AgeGreater20 { public :	bool  operator () (const  Person& p)  	 {		return  p.m_Age > 20 ; 	} }; void  test02 ()  {	vector <Person>v; 	Person p1 ("s1" ,11  )  ; 	Person p2 ("s2" ,22  )  ; 	Person p3 ("s3" ,33  )  ; 	Person p4 ("s4" ,44  )  ; 	v.push_back(p1);  	v.push_back(p2);  	v.push_back(p3);  	v.push_back(p4);  	int  num = count_if(v.begin(), v.end(),AgeGreater20()); 	cout  << num << endl ; } int  main (void )  {	test01(); 	test02(); 	system("pause" ); 	return  0 ; } 
 
常用的排序算法 学习目标 : 掌握常用的排序算法。
算法简介 :
sort 功能描述 :
对容器内元素进行排序。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v; 	v.push_back(20 ); 	v.push_back(10 ); 	v.push_back(60 ); 	v.push_back(5 ); 	v.push_back(30 ); 	v.push_back(2 ); 	 	sort(v.begin(), v.end()); 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; 	 	sort(v.begin(), v.end(), greater<int >()); 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : sort属于开发中最常用的算法之一,需熟练掌握。
random_shuffle 功能描述 : 洗牌 指定范围内的元素随机调整次序。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  #include <ctime>  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v.push_back(i); 	} 	for_each(v.begin(), v.end(),myPrint); 	cout  << endl ; 	random_shuffle(v.begin(), v.end()); 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; } int  main (void )  {	srand((unsigned  int )time(NULL )); 	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : random_shuffle洗牌算法比较使用,使用时记得加随机数种子。
merge 功能描述 : 两个容器元素合并,并存储到另一个容器中。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v1; 	vector <int >v2; 	for  (int  i = 0 ; i < 5 ; i++) 	{ 		v1.push_back(i); 		v2.push_back(i+5 ); 	} 	 	vector <int >vTarget; 	vTarget.resize(v1.size() + v2.size()); 	merge(v1.begin(),v1.end(),v2.begin(),v2.end(),vTarget.begin()); 	for_each(vTarget.begin(), vTarget.end(), myPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
merge合并的两个容器必须得是有序序列。
reverse 功能描述 : 将容器内元素进行反转。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v; 	v.push_back(20 ); 	v.push_back(10 ); 	v.push_back(60 ); 	v.push_back(5 ); 	v.push_back(30 ); 	v.push_back(2 ); 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; 	reverse(v.begin(), v.end()); 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : reverse反转区间内元素,面试题可能涉及到。
常用的拷贝和替换算法 学习目标 :
掌握常用的拷贝和替换算法。
算法简介 :
copy 功能描述 :
容器内指定范围的元素拷贝到另一容器中。
函数原型 “
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v1; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 	} 	vector <int >v2; 	v2.resize(v1.size()); 	copy(v1.begin(), v1.end(), v2.begin()); 	for_each(v2.begin(), v2.end(), myPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : 利用copy算法在拷贝时,目标容器记得提前开辟空间。
replace 功能描述 : 将容器内指定范围的旧元素修改为新元素。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v; 	v.push_back(20 ); 	v.push_back(10 ); 	v.push_back(60 ); 	v.push_back(50 ); 	v.push_back(30 ); 	v.push_back(20 ); 	cout  << "替换前"  << endl ; 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; 	cout  << "替换后"  << endl ; 	replace(v.begin(), v.end(), 20 , 2000 ); 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : replace会替换区间内满足条件的所有元素。
replace_if 功能描述 : 将区间内满足条件的元素,替换成指定元素。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream>  #include <vector>  #include <algorithm>  #include <functional>  using  namespace  std ;void  myPrint (int  val)  {	cout  << val << " " ; } class  Great30 { public :	bool  operator () (int  val)  	 {		return  val > 30 ; 	} }; void  test01 ()  {	vector <int >v; 	v.push_back(20 ); 	v.push_back(10 ); 	v.push_back(60 ); 	v.push_back(50 ); 	v.push_back(30 ); 	v.push_back(20 ); 	cout  << "替换前"  << endl ; 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; 	cout  << "替换后"  << endl ; 	replace_if(v.begin(), v.end(),Great30(),3000 ); 	for_each(v.begin(), v.end(), myPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : replace_if按条件查找,可以利用仿函数灵活筛选满足的条件。
swap 功能描述 :互换两个容器的元素。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream>  #include <algorithm>  #include <string>  #include <functional>  #include <vector>  using  namespace  std ;void  MyPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v1; 	vector <int >v2; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 		v2.push_back(i+100 ); 	} 	cout  << "交换前"  << endl ; 	for_each(v1.begin(), v1.end(), MyPrint); 	cout  << endl ; 	for_each(v2.begin(), v2.end(), MyPrint); 	cout  << endl ; 	cout  << "交换后"  << endl ; 	swap(v1, v2); 	for_each(v1.begin(), v1.end(), MyPrint); 	cout  << endl ; 	for_each(v2.begin(), v2.end(), MyPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : swap交换容器时,注意交换的容器是同种类型。
常用算数生成算法 学习目标 : 掌握常用的算数生成算法。
注意 : 算数生成算法属于小型算法,使用时包含的头文件为#include< numeric >
算法简介 :
accumulate 功能描述 : 计算区间内容器元素累计总和。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream>  #include <vector>  #include <numeric>  using  namespace  std ;void  MyPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v; 	for  (int  i = 0 ; i <= 100 ; i++) 	{ 		v.push_back(i); 	} 	 	int  total = accumulate(v.begin(), v.end(), 0 ); 	cout  << total << endl ; 	 } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 : accumulate使用时头文件注意是numeric,这个算法很实用。
fill 功能描述 :
向容器中填充指定的元素。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream>  #include <algorithm>  #include <numeric>  #include <vector>  #include <algorithm>  using  namespace  std ;void  MyPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v; 	v.resize(10 );      	fill(v.begin(),v.end(),100 ); 	for_each(v.begin(), v.end(), MyPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :利用fill可以将容器区间内元素填充为指定的值。
常用集合算法 学习目标 :
掌握常用的集合算法。
算法简介 :
set_intersection 功能描述 : 求两个容器的交集。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream>  #include <algorithm>  #include <string>  #include <functional>  #include <vector>  #include <algorithm>  using  namespace  std ;void  MyPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v1; 	vector <int >v2; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 		v2.push_back(i+5 ); 	} 	vector <int >vTarget; 	 	vTarget.resize(min(v1.size(),v2.size())); 	 	vector <int >::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin()); 	 	for_each(vTarget.begin(), itEnd, MyPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
求交集的两个容器必须得是有序序列。 
目标容器开辟空间需要从两个容器中取小值。 
set_intersection返回值(迭代器)是交集中最后一个元素的位置。 
 
set_union 功能描述 : 求两个集合的并集。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream>  #include <algorithm>  #include <vector>  using  namespace  std ;void  MyPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v1; 	vector <int >v2; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 		v2.push_back(i+5 ); 	} 	vector <int >vTarget; 	vTarget.resize(v1.size() + v2.size()); 	vector <int >::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin()); 	for_each(vTarget.begin(), itEnd, MyPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
求并集的两个集合必须得是有序序列。 
目标容器开辟空间需要两个容器相加。 
set_union返回值(迭代器)是并集中最后一个元素的位置。 
 
set_difference 功能描述 : 求两个集合的差集。
函数原型 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include <iostream>  #include <algorithm>  #include <vector>  using  namespace  std ;void  MyPrint (int  val)  {	cout  << val << " " ; } void  test01 ()  {	vector <int >v1; 	vector <int >v2; 	for  (int  i = 0 ; i < 10 ; i++) 	{ 		v1.push_back(i); 		v2.push_back(i+5 ); 	} 	 	vector <int >vTarget; 	 	vTarget.resize(max(v1.size(), v2.size())); 	cout  << "v1和v2的差集"  << endl ; 	vector <int >::iterator itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin()); 	 	for_each(vTarget.begin(),itEnd, MyPrint); 	cout  << endl ; 	cout  << "v2和v1的差集"  << endl ; 	itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin()); 	for_each(vTarget.begin(), itEnd, MyPrint); 	cout  << endl ; } int  main (void )  {	test01(); 	system("pause" ); 	return  0 ; } 
 
总结 :
求差集的两个集合必须得是有序序列。 
目标容器开辟空间需要从两个容器取较大值。