C++STL的学习

范型程序设计:
template
T表示的不再是单一的数据类型。
STL: Standard Template Library
STL是算法 泛型算法 和其他的一些组件的集合
STL是C++标准的一个重要的组成部分。
STL的主要组件://他并不是仅仅针对某种类型而是对于很多类型。
container(容器)
algorithm(算法)
iterator(迭代器)
function object(函数对象)

#include
#include
#include//动态数组
#include
#include
using namespace std;
int main()
{	
	const int N= 5;
	vector<int>s(N);//申请一个长度为5的数组
	for(int i=0;i<N;i++)
		cin>>s[i];
	transform(s.begin(),s.end(),ostream_iterator<int>(cout," "),negate<int>());
	cout<<endl;
}

容器:容纳,包含一组数据元素的对象,支持了软件设计中常用的先行群体。
迭代器:提供的顺序访问容器中每个元素的方法,含类似指针的用法。
程序中有:(迭代器)
s.begin();容器s的第一个元素
s.end();容器s的最后一个元素的后面。
ostream_iterator(cout," ");构造出来的输出迭代器对象,通过cout输出int型数据,中间用空格(“ ”)隔开。
用迭代器要用#include
算法:STL提供大量具有统一性的算法,可以广泛用于不同的对象和内置函数类型。

迭代器对于存储在容器中的元素序列进行遍历,提供的访问容器中每个元素的方法。
指针是迭代器中的一种,
输入流迭代器和输出流迭代器
输入流,输出流
1.标准类:stream,ostream
2 实例 cin ,cout
输入流迭代器
templateistream_iterator
要求:T类型重载了运算符>>
以输入流为参数构造:
istream_iterator(cin);
istream_iterator();//指向输入流结束的位置
输出流迭代器
temlateostream_iterator
要求:T类型重载了运算符<<
以输入流为参数构造:
ostream_iterator(cout);
ostream_iterator(cout,分隔符);

#include
#include
#include
using namespace std;
double square(double x)
{
	return x*x;
}
int main()
{
	transform(istream_iterator<double>(cin),istream_iterator<double>(),ostream_oterator<double>(cout," "),square);
	cout<<end;
	return 0;
}

再例:

#include
#include
#include
#include
using namespace std;
template <calss T,class InputIterator,class OuputInputIterator>
void mySort(inputIterator first,InputIterator last,Outputiterator result)
{
	vector<T>s;
	for(;first!=lats;first++)
		s.push_back(*first);
	sort(s.begin(),s.end());
	copy(s.begin(),s.end(),result);
}
int main()
{
	double a[5]={1.2,2.4,0.8,3.3,3.2};
	mySort<double>(a,a+5,ostream_iterator(cout," "));
	cout<<endl;
	cout<<"Input data";
	mySort<int>(istream_iterator<int>cin,istream_iterator<int>(),ostream<int>(cout," "));//输入流通过键盘来获取输入并通过显示屏显示输出
	cout<<endl;
	return 0;
}

迭代器的辅助函数
对pos执行n次自增加操作
计算两个迭代器之间的距离

容器的分类
容器是容纳,包含一组元素或元素集合的对象
七种基本容器:
向量(vector)
双端队列(deque)
列表(list)
集合(ste)
多重集合(multiset)
樱色(map)
多重集合(multimap)
按容器中元素的组织方式
顺序容器
关联容器
按与容器相关的迭代器类型
可逆容器
随机访问

容器 顺序容器 关联容器
可逆容器 list set multiset/map/multimap
随机访问容器 vector/deque

对于容器的通用功能
容器的通用功能
用默认构造函数构造空容器
支持关系运算符:== ,!= , < , <=, > , >=
clear():将容器清空
empty():判断容器是否为空
size():得到容器元素个数
s1.swap(s2):将s1和s2两个容器内容交换
随机访问容器获得容器s的第n个元素
s[i]获得容器s的第n个元素

相关迭代器类型(s表示容器类型)
s.iterator:指容器元素的迭代器类型
s::const_iterator:常迭代器类型
实例:vector::iterator pos;
vector::const_iterator cpos;//常迭代器不能修改

顺序容器的基本功能
构造
s.

赋值 assign

插入:s.insert(p1,n,t); s.insert(p1, q1, q2);//p1为迭代器在改为插入n个t元素
s.push_front(t);//在前面插入数据元素
s.push_back();//在后面插入数据元素

删除
s.erase(p1);s.erase(),s.clear()//清理p1迭代器后面的元素
s.pop_front();s.pop_back();//对list和deque//删除前面的元素,删除后面的元素。

改变大小
s.resize();

向量(vector)
特点:
一个可以扩张的动态数组
随机访问
在尾部插入或删除一个元素快,在中间或则头部插入元素慢,

向量的容量
容量(capacity):实际分配空间的大小
s.capacity():返回当前容量
s.reserve(n):若容量小于n,则对s进行扩展,使其容量至少为n。

#include
#include
#include
#include
#include
using namespaace std;
int main()
{
	const int N=5;
	vector<int>s;
	s.reserve(3);
	cout<<"capacity: "<<s.capacity()<<"size:"<<s.size()<<endl;
	for(int i=0;i<N;i++)
		s.push_back();
	s.insert(s.begin()+3,9);
	copy(s.begin(),s.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
	s.pop_back();
	copy(s.begin(),s.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
	return 0;
}

双端队列

特点:
在两段插入或删除元素快
在中间插入或删除元素慢
随机访问较快,但比向量容器慢

存储结构
数组
分段数组
再例:奇偶排序
先按照从大到小顺序输出奇数,
再按照从小到大顺序输出偶数。

#include
#include
#include
#include
#include
using namespace std;
int main()
{
	istream_iterator<int> i1(cin),i2;
	vector<int> s1(i1,i2);//将迭代器i1和i2之间的数据放入向量中
	sort(s1.begin(),s1.end());//排序
	copy(s1.begin(),s1.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
	deque<int>s2;
	for(vector<int>::iterator iter=s1.begin();iter!=s1.end();iter++)
	{
		if(*iter%2==0)
			s2.push_back(*iter);
		else
			s2.push_front(*iter);
	}
	copy(s2.begin(),s2.end(),ostream_iterator<int>(cout," "));
	cout<<endl;
	return 0;
}

列表(list)
特点
再任意位置插入和删除元素都很快
不支持随机访问
接和splice操作
s1.splice(p,s2,q1,q2);将s2中[q1,q2]移动到s1中p所指向元素之前

#include
#include
#include
#include
using namespace std;
int main()
{
	string names1[]={"Alice","Helen","Lucy","Susan"};
	string namas2[]={"Bob","David","Levin","Mike"};
	list<string>s1(names1, names1+4);
	list<string>s2(names2,names2+4);
	s2.splice(s2.end(),s1,s1.begin());
	advance(iter1, 2);
	list<string>::iterator iter2=s2.begin();
	++iter2;
	list<string>::iterator iter3=iter2;
	advance(iter3,2);
	s1.splice(iter1,s2,iter2,iter3);
	copy(s1.begin(),s1.end(),ostream_iterator<string>(cout," "));
	cout<<endl;
	copy(s1.begin(),s2.end(),ostream_iterator<string>(cout," "));
	cout<<endl;
	return 0;
}

三种顺序容器的比较与选用
1.如果需要执行大量的随机访问操作,而且扩张容器只需要向容器尾部加入新的元素。就应当选用向量容器
vector;
2.如果需要少量的随机访问需要在容器两端插入删除元素,则应当选择双端队列容器deque
3.如果不需要对容器进行随机访问,但是需要在中间位置插入或者删除元素,就应当选择列表容器list
关联容器的特点
每一个关联容器都有一个键值(Key)
每个元素按键的取值升序排列
(对于一个关联容器,使用迭代器s在区间[s.begin(),s.end()])内遍历,访问到的序列总是升序
优势
可以根据键值高效地直接查找元素
要求:键的类型必须能够用<比较
int,double等基本数据类型
其他重载<运算符的类型
例:学生表的存储
class Student()
mapstudents;

简单关联容器-集合(set)
数学中的集合
一些同质元素的共同体
不含重复的元
有限集合/无限集合
STL中的set

存储一组数据(数据类型相同)
无重复
有序
有限集合

#include
#include
#include
#include
using namespace std;
int main()
{
	set<double>s;
	pair<set<double>::iterator,bool>r;
	while(true)
	{
		double v;
		cin>>v;
		r=s.insert(v);//插入完以后会将值赋值给r此时的r有两个值第一个字是插入的数据,第二个是返还的布尔值
		if(!r.second)//即为r布尔值,集合当中是否已经存在v了如果存在则返回false如果不存在则返回true。
			cout<<v<<"duplicated\n";
	}
	set<double>::iterator iter1=s.begin();
	set<double>::iterator iter2=s.end();
	double medium = (*iter1 + *(--iter2))/2;
	cout<<"<=midnum";
	copy(s.begin(),s.upper_bound(medium),ostream_iterator<double>(cout," "));
	cout<<endl;
	cout<<">=medium";
	copy(s.lower_bound(medium),s.end(),ostream_iterator<double>(cout," "));
	cout<<endl;
}//插入完的数据具有有序性

关联容器的操作:以set为例
插入:insert()
删除:earse()
查找:find(k)
定界
lower_bound(k); 返回第一个不小于k元素的迭代器
upper_bound(k); 返回第一个大于k元素的迭代器
count(k); 计数

映射(map)
映射与集合相同点
一组无重复有序数据
映射与集合主要区别
集合的元素类型是键本身
映射的元素类型是由键和附加数据所构成的二元组
mapcourse;
在影射中按键值查找一个元素时,除了能确定他的存在性外,还可以得到相应的附加数据。
map的元素类型是–pair
template
struct pair{
T1 first;
T2 second;

}

#include
#include
#include
#include
using namespace std;
int main()
{
	map<string, int>courses;
	map<string,int>::iterator iter;//定义这种类型数据的迭代器
	string name;
	course.insert(make_pair("CSAPP",3));//把添加的数据转换为pair类型
	course.insert(make_pair("C++,2"));
	cousre.insetr(make_pair("CSARCH",4));
	course.insert(make_pair("COMPILER",4));
	course.insert(make_pair("OS",5));
	int n=3;
	int sum=0;
	//选三门课计算学分
	while(n)
	{
		cin>>name;
		iter=courses.find(name);
		if(iter==courses.end())
		{
			cout<<name<<"is not available\n";
		}
		else{
			sum+=iter.second;//第二个部分即为学分
			courses.erase(iter);//从map中删除三门课程
			n--;
		}
	}
	cout<<"Total credit:"<<sum<<endl;
	
}

函数对象:一个行为类似函数的对象
可以没有参数,也可以带有若干参数。
其功能是获取一个值,或则改变操作的状态。
函数对象的形式
普通对象的形式
普通函数就是函数的对象

为什么要用函数适配器
例:有
int intArr[8]={30,90,10,40,70,50,20,80};
vectora(intArr,intArr+8);
用find_if查找满足第一个大于40的元素
vector::iterator p=find_if(a.begin(),a.end(),greater40);
期望
用一个一般性函数完成类似greater40的功能
通用功能
键一种函数对象,转换为另一种复合要求逻辑的函数。

#include
#include
#include
#include
using namespace std;
struct Car
{
	int id;
	Car(int id)
	{
		this->id=if;
	}
	void displya()
	{
		cout<<"car"<<id<<endl;
	}
}
int main()
{
	vector<Car *>pcars;
	vector<Car>cars;
	for(int i=5;i<10;i++)
	{
		pcars.push_back(new Car(i));//
	}
	for(int i=5;i<10;i++)
	{
		cars.push_back(Car(i));//
	}
	cout<<"elements in pcars:"<<endl;
	for_earch(pcars.begin(),pcars.end(),mum_fun*(&Car::display);//使成员函数作为函数对象,传入对象指针
	cout<<endl;
cout<<"elements in cars:"<<endl;
for_earch(cars.begin(),cars.end(),mem_fun_ref(&Car::display));//使成员函数作为函数对象,传入对象引入
cout<<endl;
for(size_t i =0;i<pcars.size();++i)
	delete pcars[i];
return 0;
}

STL算法本身是一种函数模板
通过迭代器获得输入数据
通过函数对象对数据进行处理
通过迭代器将结果输出
STL算法是通用的,独立于具体的数据类型,容器类型
STL算法分类
不可变序列算法
可变序列算法
排序和搜索算法
数字算法
不可变序列算法
不直接修改所操作的容器内容的算法
用于查找指定元素,比较两个序列是否相同,对元素进行技术等。
包括
find()?/在区间中查找某个值首次出现的位置
count();//返回特定值在区间中出现的次数
equal();//比较两个序列元素是否相同
排序和搜索算法
1.对序列进行排序
2.对两个有序序列进行合并
3.对有序序列进行搜索
4.有序序列的集合操作
5.堆算法
sort(begin,end);//默认为<号排序,也可以通过重载<号进行。

你可能感兴趣的:(C++STL的学习)