1.STL(Standard Template Library,是用泛型技术来设计完成的实例)的概念与组成
Iterator(迭代器)
Container(容器)
Algorithm(算法)
Adaptors(配接器)
STL的六大组件分别是:
容器(Container)
算法(Algorithm)
迭代器(Iterator)
仿函数(Function object)
适配器(Adapter)
空间配置器(allocator):只能分配内存等
2.容器与算法
案例如下:
#include<iostream>
#include<vector>//容器
#include<array>//数组
#include<algorithm>
usingnamespacestd;
//实现一个模板类,专门实现打印的功能
template<classT> //类模板实现了方法
classmyvectorprint
{
public:
void
operator ()(constT
&t)//重载,使用(),打印
{
std::cout
<< t <<std::endl;
}
};
voidmain()
{
vector<int> myvector;
myvector.push_back(11);
myvector.push_back(21);
myvector.push_back(31);
myvector.push_back(81);
myvector.push_back(51);
array<int,
10> myarray = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
myvectorprint<int>print;//对于打印进行实例化
//begin,endl迭代器,是一个指针
for_each(myvector.begin(),myvector.end(),print);
std::cout
<< "---------------------" <<std::endl;
for_each(myarray.begin(),myarray.end(),print);
cin.get();
//算法可以适用于任何一个容器,for_each是一个算法
}
3.容器
序列式容器(Sequence containers)
每个元素都有固定位置----取决于插入实际和地点,和元素之无关
Vector,deque,list
关联式容器(Associated containers)
元素位置取决于特定的排序准则,和插入顺序无关
set、multiset、map、multimap
4.vectors:
将元素置于一个动态数组中加以管理
可以随机存取元素(用索引直接存取)
数组尾部添加或移除元素非常快速,但是在中部或头部安插元素比较费时。
5.数组线程容器
#include<iostream>
#include<vector>
#include<array>
#include<tuple>
usingnamespacestd;
voidmain()
{
//数组,静态数组,栈上
array<int,
5> myarray = { 1, 2, 3, 4, 5 };
//动态数组,堆上
vector
<int>myvector;
myvector.push_back(1);
//不需要变长,容量较小时,使用array
//不需要变长,容量较大是,使用vector
}
6.list容器(添加和迭代输出)
#include<iostream>
#include<hash_set>
#include<list> //实际上是一个双向链表
#include<stdio.h>
//list使用于经常插入,经常删除
usingnamespacestd;
voidmain()
{
list<int>mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
mylist.push_back(4);
mylist.push_front(4);//往头部插入
//指针,指向一个迭代器,迭代器存储了位置
autoibegin
=mylist.begin();
autoiend
=mylist.end();
//list用迭代器进行遍历
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
printf("%p,&p\n",ibegin._Ptr,ibegin);//重载
}
cin.get();
}
运行结果是:
7.list删除应该注意的地方
#include<iostream>
#include<hash_set>
#include<list> //实际上是一个双向链表
#include<stdio.h>
//list使用于经常插入,经常删除
usingnamespacestd;
voidmain()
{
list<int>mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
mylist.push_back(4);
mylist.push_back(5);
//auto i = mylist.begin();删除元素,依赖于迭代器
//++i
//++i
//++i
autoi
=mylist.end();//end最后一个没有实体
i--;
mylist.erase(i);//链式存储,不允许下标访问
//只能用迭代器,链表迭代器只能用++,--
//mylist.clear();清空
//指针,指向一个迭代器,迭代器存储了位置
autoibegin
=mylist.begin();
autoiend
=mylist.end();
for
(;ibegin !=iend;ibegin++)
{
if
((*ibegin) == 3)
{
mylist.erase(ibegin);//删除,删除的时候迭代器会发生
break;//这里一定要记住,要使用break;因为list原来的结构已经发生了变化
}
//cout <<*ibegin << endl;
}
{
//指针,指向一个迭代器,迭代器存储了位置
autoibegin
=mylist.begin();
autoiend
=mylist.end();
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
}
}
cin.get();
}
运行结果:
8.通过数组的方式为list初始化
#include<iostream>
#include<hash_set>
#include<list> //实际上是一个双向链表
#include<stdio.h>
//list使用于经常插入,经常删除
usingnamespacestd;
voidmain()
{
inta[5]
= { 1, 2, 3, 4, 5 };
list<int>mylist(a,a
+ 5);//根据数组初始化
//传递开始地址,传递结束地址
//mylist(0)
//mylist[1];只能用迭代器访问
mylist.push_back(10);
mylist.push_front(12);//在前添加数值
//指针,指向一个迭代器,迭代器存储了位置
autoibegin
=mylist.begin();
autoiend
=mylist.end();
for
(;ibegin !=iend;ibegin++)
{
if
(*ibegin == 3)
{
mylist.insert(ibegin,
30);
break;//删除或者插入,迭代器都会发生变化
}
}
mylist.remove(30);//直接一个函数,根据元素来删除
{
autoibegin
=mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
autoiend
=mylist.end();
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
}
}
cin.get();
}
运行结果:
9.数组初始化,并逆向输出
#include<iostream>
#include<hash_set>
#include<list> //实际上是一个双向链表
#include<stdio.h>
//list使用于经常插入,经常删除
usingnamespacestd;
voidmain()
{
inta[5]
= { 1, 2, 3, 4, 5 };
list<int>mylist(a,a
+ 5);//根据数组初始化
autorb
=mylist.rbegin();
autore
=mylist.rend();
//同时正向方向查找
for
(;rb !=re;rb++)
{
cout
<< *rb <<endl;
}
cin.get();
}
运行结果:
10.list合并,排序
#include<iostream>
#include<hash_set>
#include<list> //实际上是一个双向链表
#include<stdio.h>
//list使用于经常插入,经常删除
usingnamespacestd;
voidmain()
{
inta[5]
= { 1, 2, 3, 104, 5 };
list<int
> mylist1(a,a
+ 5);//根据数组初始化,
intb[5]
= { 11, 122, 33, 44, 55 };
list<int
> mylist2(b,b
+ 5);//根据数组初始化,
mylist1.sort();
mylist2.sort();//两个list合并到list之前需要数组排序
mylist1.merge(mylist2);//合并之前必须有序
{
autoibegin
=mylist1.begin();//指针,指向一个迭代器,迭代器存储了位置
autoiend
=mylist1.end();
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
}
}
cout
<<"\n\n\n";
{
autoibegin
=mylist2.begin();//指针,指向一个迭代器,迭代器存储了位置
autoiend
=mylist2.end();
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
}
}
cin.get();
}
运行结果:
11.list中通过unique()方法去掉重复的元素
#include<iostream>
#include<hash_set>
#include<list> //实际上是一个双向链表
#include<stdio.h>
//list使用于经常插入,经常删除
usingnamespacestd;
voidmain()
{
inta[6]
= { 1, 2, 98, 2, 5, 98 };
list<int>mylist1(a,a
+ 6);//根据数组初始化
{
autoibegin
=mylist1.begin();
autoiend
=mylist1.end();
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
}
}
mylist1.sort();
mylist1.unique();//唯一依赖于排序,通过这个方法实现了去掉重复的
cout
<<"\n\n\n";
{
//指针,指向一个迭代器,迭代器存储了位置
autoibegin
=mylist1.begin();
autoiend
=mylist1.end();
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
}
}
cin.get();
}
运行结果:
list迭代输出
#include<iostream>
#include<set>
#include<stdio.h>
#include<list>
#include<vector>
#include<algorithm>
#include<functional>
usingnamespacestd;
voidmain()
{
list<int>mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
mylist.push_back(4);
//mylist[1];
autoibegin
=mylist.begin();//指针,指向一个迭代器,迭代器存储了位置
autoiend
=mylist.end();
//list用迭代器进行遍历
for
(;ibegin !=iend;ibegin++)
{
cout
<< *ibegin <<endl;
printf("%p,%p\n",ibegin._Ptr,ibegin);//重载
}
cin.get();
}
运行结果:
12算法find
#include<algorithm>
#include<iostream>
usingnamespacestd;
structprint
{
void
operator()(intx)//重载了()符号,直接调用()
{
std::cout
<< x <<endl;
}
};
voidprintA(intx)
{
std::cout
<< x <<endl;
}
//find这个算法
voidmain()
{
inta[10]
= { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int
*p =find(a,a
+ 10, 8);
std::cout
<< (void*)a
<< (void*)(a
+ 10) << std::endl;
std::cout
<< *p <<endl;
std::cout
<< p <<endl;
if
(p == (a
+ 10))
{
std::cout
<< "没有找到\n";
}
//下面的方式是调用重载的print函数
for_each(a,a
+ 10,print());//遍历每一个元素
//printA是一个函数指针,必须是函数类型
std::cout
<< "-------------------------" <<std::endl;
for_each(a,a
+ 10,printA);
cin.get();
}
运行结果:
13.find_if,bind1st,仿函数
#include<iostream>
#include<set>
#include<stdio.h>
#include<list>
#include<vector>
#include<algorithm> //find_if的头文件
#include<functional> //仿函数需要这里
usingnamespacestd;
boolless3(intx)
{
returnx
< 3;
}
voidmain()
{
vector<int>mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(16);
mylist.push_back(17);
mylist.push_back(18);
autoib
=mylist.begin();
autoie
=mylist.end();
for
(;ib !=ie;ib++)
{
std::cout
<< *ib <<std::endl;
}
//防函数可以实现一定的算法策略
//bind1st表示要绑定一个函数
//绑定一个函数,greater<int>(),3,表示比三大的数
//查找第一个比3大的数值,下面的代码的意思是找到第一个3比取出的数值大的数的位置
autoifind
=find_if(++mylist.begin(),mylist.end(),bind1st(greater<int>(),
3));
std::cout
<< "\n\n\n\n" << *ifind
<< endl;
std::cout
<< "---------------------" <<std::endl;
autoifind2
=find_if(mylist.begin(),mylist.end(),less3);
std::cout
<< "\n\n\n\n" << *ifind
<< endl;
cin.get();
}