stack容器
stack<int> s;
s.pop();//出栈
s.push(num);//入栈
if(!s.empty())
s.size();//栈的大小
没有迭代器,不能操作数据,FILO
queue容器
FIFO,没有迭代器
queue<int> q;
q.push(n);
q.pop();
q.back();//队尾元素
q.front();//队头元素
if(!q.empty)//队头不空
q.size();//队列的大小
list容器
list容器是一个循环双向链表
空间和时间额外消耗较大。
list<int> l;
l.pushback();
l.pushfront();
l.popback();
l.popfront();
l.insert(l.begin(),1000);//在begin()处插入1000
l.remove(n);//删除容器中所有与n匹配的元素
l.size();//大小
if(!l.empty())
l.resize();
l.swap()
//反转排序
list<int> l;
l.reverse();
//所有不支持随机访问的迭代器,不可以使用系统提供的算法例如sort(),如果不支持用系统提供算法,那么这个类内部会提供
l.sort(cmp);//与sort用的方法一样,同样可以写回调函数
重载 == 让remove可以删除自定义类型
class person
{
public:
template<class T>
bool operator==(const person &p)//必须加const
{};
}
for (iterator _First = begin(); _First != end(); )
if (*_First == _Val)//重载这个==号
if (_STD addressof(*_First) == _STD addressof(_Val))
_Val_it = _First++;
else
_First = erase(_First);
else
++_First;
if (_Val_it != end())
erase(_Val_it);
}
set/multiset容器(关联式容器)
set不允许键值重复,而multiset允许键值重复
自动排序,从小到大
set的键值就是实值
set<int> s1;
multiset<int> s2;
s1.insert(n);//只能这样插入数据
s1.erase(可以加迭代器或者值);
有很多相同的的api就不写了
//查找操作
set<int>::iterator pos = s1.find(n);//返回的是一个迭代器,如果没找到返回的就为s1.end()
int n = s1.count(n);//对于set来说,n只可能为0/1,而multiset可能为任何值。查找n的个数。
set<int>::iterator pos = s1.lower_bound(n);//返回第一个key>=n(注意是大于等于)元素的迭代器,如果没找到返回的就为s1.end()
set<int>::iterator pos = s1.upper_bound(n);//返回第一个key>n(注意是大于)元素的迭代器,如果没找到返回的就为s1.end()
equal_range(n);//返回lower_bound和upper_bound两个迭代器,每个迭代器如果没找到返回的就各自返回s1.end()
pair<set<int>::iterator,set<int>::iterator> ret = s1.equal_range(n);
ret.first;//第一个迭代器 lower_bound
ret.second;//第二个迭代器 upper_bound
//pair对组
pair<elemtype,elemtype> p(...,...);
p.first;
p.second;//第一种方式
pair<elemtype,elemtype> p2 = make_pair(...,...);
//第二种方式
pair<set<int>::iterator,bool> ret = s1.insert(n);
//插入成功ret.second = true; 插入键值不能相同
//从大到小排序,只能在插入之前制定规则
//仿函数
class cmp{
public:
bool operator()(int v1,int v2)//重载括号
return v1 > v2;
};
set<int,cmp> s;//当然迭代器也要加上仿函数了
s.insert();
//自定义数据类型必须先制定排序规则
map/multimap容器
map的所有元素都是pair,第一元素为key值,第二元素为value值 允许两个元素有相同的value值,但不能有相同的key值,会根据key的大小自动排序。multimap的键值可重复
map<int,int> m;
//4种方式插入
m.insert(pair<int,int>(1,10));
m.insert(make_pair(2,20));//推荐方法
m.insert(map<int,int>::value_type(3,30));
m[4] = 40;//但是有风险 直接写一个 m[5] 也会成功,并且给m[5]赋值为0
for(map<int,int>::iterator it = m.begin(); it != m.end(); it++)
cout << it->first << " " << it->second <<endl;
//it指的是pair,当然也可以用(*it).first
//删除查找
m.erase(n);//删除value值为n的对组
同时也可以像set一样指定排序规则,但是只是对键值进行排序。
class cmp{
public:
bool operator ()(int n1,int n2){
return n1 > n2;
}
};
map<int,string,cmp> m;
要想对value值进行排序,可以先放入一个序列式容器,
typedef pair<int,string> p;
map<int,string> m;
m.insert(make_pair(...,...));//存入数据
vector<p> mv(m.begin(),m.end());//转存数据到vector
bool cmp(p &p1,p &p2){
return p1.second > p2.second;
}
sort(p.begin(),p.end(),cmp);//对value排序
stl容器使用时机
常用算法
函数对象(又称仿函数)
重载的operator()()第二个括号中有一个参数称为1元仿函数,有两个称为2元仿函数
可以保存状态,比如说调用了多少次仿函数就可以在对象中加入一个成员count。
函数对象还可以作为参数
谓词
函数或者仿函数返回对象是bool类型,就叫谓词。
接收一个参数就叫一元谓词,两个就二元。
class func{
public:
bool operator()(int n)
return n > 20;
};
vector<int>::iterator it = find_if(v.begin(),v.end(),fun());//第三个是一个函数对象,而不是数据类型,返回一个迭代器
//匿名函数 lambada表达式[](){};
for_each(v.begin(),v.end(),[](int val){ cout << val << " "; });
内建函数对象
#include <functional>
negate<int> n;
cout << n(10) << endl;//打印出-10
plus<int> p;
cout << p(10,20) << endl;//打印出30
sort(v.begin(),v.end(),greater<int>());//排序算法
适配器使用
#include <functional>
using namespace std;
class my:public binary_function<int,int,void>//第二步,继承,参一为operator()参一类型,参二为operator()参二类型,参三为函数返回值
{
public:
void operator()(int a,int b) const{ //第三步,加const,防止修改
cout << a + b << endl;
}
};
int main()
{
vector<int> v(10);
for (int i = 0; i < 10; i++)
v[i] = i;
int num = 10;
for_each(v.begin(), v.end(), bind2nd(my(), num));//第一步,绑定bind1st为将num绑定为第一个参数,bind2nd为将num绑定为第二个参数,操作的都是num,也就是将num绑定为a或者b的区别
return 0;
}