作用:获得[first,last)所表示序列的下一个排列组合
如果没有,返回false;
否则返回true
算法:
1- 从最尾端往前搜索两个相邻元素,零第一个元素为*i,第二个为*ii,并满足:*i<*ii;
2- 再从尾端开始往前检验,找出第一个大于*i的元素,令为*j,对调i,j指向元素;
3- 将ii后的所有元素颠倒
例子
bool next_permutation(char*first,char*last)
{
if(first==last)return false;//空区间
char *i=first;
++i;
if(i==last)return false;//只有一个元素
i=last;//尾端
--i;
for(;;)
{
char *ii=i;
--i;
if(*i<*ii)
{
char *j=last;
while(!(*i<*--j));
swap(*i,*j);
reverse(ii,last);
return true;
}
if(i==first)
{
reverse(first,last);
return false;
}
}
}
算法:
1-尾端往前搜索两个相邻元素,零第一个元素为*i,第二个为*ii,并满足:*i>*ii;
2-端开始往前检验,找出第一个小于素,令为*j,对调i,j指向元素;
3-ii的所有元素颠倒
bool prev_permutation(char*first,char*last)
{
if(first==last)return false;//空区间
char *i=first;
++i;
if(i==last)return false;//只有一个元素
i=last;//尾端
--i;
for(;;)
{
char *ii=i;
--i;
if(*i>*ii)
{
char *j=last;
while(!(*i>*--j));
swap(*i,*j);
reverse(ii,last);
return true;
}
if(i==first)
{reverse(first,last);return false;}
}
}
random_shuffle
for i=1~n-1
swap(a[i],a[rand()%(i+1)])
template <class T>
T power (T x,int n)
{
if(n==0)return 1;
else
{
Tresult=1;
if(n&1!=0)//n为偶数
{//result=x,n=n-1或者n=n&0;
result=x;n=n&0;
}
//n为奇数或偶数时的公共部分
while(n&1==0)
{
x=x*x;
n>>=1;
}
result*=x;
}
return result;
}
template <class T>
T power (T x,int n)
{
if(n==0)return 1;
else
{
while((n&1==0))//偶数
{
n>>=1;
x=x*x;
}
T result=x;
n>>=1;
while(n!=0)
{
x=x*x;
if(n&1!=0)奇数
result=result*x;
n>>=1;
}
result
}
}
push_heap(first,last)
pop_heap(first,last){adjust_heap}
sort_heap(first,last){一直使用pop_heap直至没有元素为止}
make_heap(first,last){调用adjust_heap}
建立堆
make_heap(_First,_Last, _Comp)
1-默认是建立最大堆的。
在堆中添加数据
push_heap(_First, _Last)
要先在容器中加入数据,再调用push_heap ()
在堆中删除数据
pop_heap(_First,_Last)
要先调用pop_heap()再在容器中删除数据
堆排序
sort_heap(_First,_Last)
int a[9]={1-9}:
vector<int>myvec(a,a+9);
make_heap(myvec.begin(),myvec.end());
///直接改变myvec
构造函数---make_heap算法,make_heap(c.begin,c.end(),comp)
push---------(1,低层容器的push_back插入末端,
2,使用push_heap算法重排heap, push_heap(c.begin,c.end(),comp)
pop---------(1,重排heap,pop_heap(c.begin,c.end(),comp)
2,底层容器的pop_back()弹出元素, c.pop_back())
通过对结构体重载operator():
1- 定义函数对象
2- 重新定义operator<函数
例子:程序功能是模拟排队过程,每人有姓名和优先级,优先级相同则比较姓名,
开始有5个人进入队列,然后队头2个人出队,再有3个人进入队列,
最后所有人都依次出队,程序会输出离开队伍的顺序。
template<class T, class C, class A>class set;
第一个T 是元素类型,必选;
第二个C 指定元素比较方式,缺省为 Less<T>, 即使用 < 符号比较;
第三个A 指定空间分配对象,一般使用默认类型。
(1) 如果使用默认值,自定义元素类型需要重载< 运算操作;
(2)不使用默认值,则比较对象必须具有() 操作,即自定义函数对象:
bool operator()(const T &a, const T&b)
即自定义一个比较函数/函数对象
所以作为关键字,起码必须有“<”这个比较操作符。
1-int,float,enum,size_t等等简单关键字,都有内置的比较函数,与map搭没什么问题。
2-自定义类型,必须明确定义“<”比较操作符,作为第三个参数。
使用map时,注意以下两点,同时这两点也是改错的方法:
a) 关键字明确定义“<”比较操作符
b) 没有“<”比较操作符,自定义仿函数替代第三个参数Compare,该仿函数实现“()”操作符,提供比较功能。插入时使用
容器增长前,能够容纳的元素总数;
只有连续存储的容器才有容量概念(vector,deque,string),list不需要;
容器当前存储的元素数量;
注:vector默认的容量初始值,增长规则依赖编译器
1, 默认构造函数(默认或自定义的)
2, 可用的拷贝构造,赋值函数(默认或自定义的)
自己的理解:如果对vector排序的话,还需要定义operator<,==等操作符
双向队列-----双向开口的连续线性空间;
高效的在头尾两端插入和删除元素;
内部会维护一个map(注意!不是STL中的map容器)即一小块连续的空间,该空间中每个元素都是指针,指向另一段(较大的)区域,这个区域称为缓冲区,缓冲区用来保存deque中的数据。因此deque在随机访问和遍历数据会比vector慢。
注意一点。对于deque和vector来说,尽量少用erase(pos)和erase(beg,end)。因为这在中间删除数据后会导致后面的数据向前移动,从而使效率低下。
1-高效的首段插入/删除,2-内存管理
以调用find()在deque中查找:
对应自定义的类和结构须添加:
booloperator == (const MyClass &other) const 成员函数;
或booloperator ==(const MyClass &one, const MyClass &another) 全局函数。如果容器中含有元素:
则程序退出前须清空调用deque的clear()或~deque(),否则出现内存泄露。
如存储的是指针类型deque<MyClass*>:
每个指针对应一个堆内存。
1-则需要使用遍历每一个元素并调用delete *iterator;来释放指针指向内存。
2-然后在清空容器(deque的clear()或~deque())