// TEMPLATE FUNCTION next_permutation
template<class _BI> inline
bool next_permutation(_BI _F, _BI _L)
{_BI _I = _L;
if (_F == _L || _F == --_I) // (1)
return (false);
for (; ; )
{_BI _Ip = _I; // (2)
if (*--_I < *_Ip) // (3)
{_BI _J = _L;
for (; !(*_I < *--_J); ) // (4)
;
iter_swap(_I, _J); // (5)
reverse(_Ip, _L); // (6)
return (true); }
if (_I == _F)
{reverse(_F, _L); // (7)
return (false); }}}
next_permutation()将[first,last)标记的排列重排为下一个排列,如果不存在下一个排列,则返回false。
源码分析(假设有容器{3,5,4,2}):
(1)、由于范型算法一般是应用在容器上,而容器是用其首元素和最后元素的下一个位置来表示其范围的,所以next_permutation()处理的 [first,last)为半开半闭区间,对于算法内部,则很明显要先对_I进行递减操作,使其指向容器的最后一个元素,如果和首元素地址相同,则为单元素容器,不存在下一个排列。
(2)、把_I的iter赋给_lp,注意对于第一次循环_I是指向最后元素了(因为(1)中有操作--I)。_Ip和_I指向容器元素5时,(3)的条件满足。
(3)、因其处在无限循环for(;;)中,故在容器中从后往前找第一个非逆序(后面的元素不小于其紧挨的之前的元素*--I<*_lp)(3,5),此时_I指向3,_lp指向5。
(4)、对_I到最后一个元素之间的元素查询是否有大于_I所指向的元素(3),有!此时_J指向元素5大于3。如果没有,那么该for循环最后_I,_J指向同一元素3,同样结束该for循环。
(5)、交换_I,_J所指向的元素。得到容器{4532}
(6)、对于_lp和_L之间的元素重新按反序排列,原来为逆序532,现在重排为235,于是得到容易{4235} ,即是容器{3542}的下一个排列。
(7)、对于已经排成完全逆序的容器,如{5432},则先将其按反序重排为完全顺序{2345},然后返回false,因为其不存在下一个排列。
注意:在求容器的下一个排列时,总是要保证容器靠前的元素最小的不同排列,且如果得到完全逆序容器,则返回false,所以如果要求一个容器的全排列,应该先对该容器进行顺序排序,最后一点经过next_permutation()操作最后返回false后的容器为顺序的,应为该算法对完全逆序容器是先反序排列了之后再返回false的。
template<class _BI> inline
bool next_permutation(_BI _F, _BI _L)
{_BI _I = _L;
if (_F == _L || _F == --_I) // (1)
return (false);
for (; ; )
{_BI _Ip = _I; // (2)
if (*--_I < *_Ip) // (3)
{_BI _J = _L;
for (; !(*_I < *--_J); ) // (4)
;
iter_swap(_I, _J); // (5)
reverse(_Ip, _L); // (6)
return (true); }
if (_I == _F)
{reverse(_F, _L); // (7)
return (false); }}}
next_permutation()将[first,last)标记的排列重排为下一个排列,如果不存在下一个排列,则返回false。
源码分析(假设有容器{3,5,4,2}):
(1)、由于范型算法一般是应用在容器上,而容器是用其首元素和最后元素的下一个位置来表示其范围的,所以next_permutation()处理的 [first,last)为半开半闭区间,对于算法内部,则很明显要先对_I进行递减操作,使其指向容器的最后一个元素,如果和首元素地址相同,则为单元素容器,不存在下一个排列。
(2)、把_I的iter赋给_lp,注意对于第一次循环_I是指向最后元素了(因为(1)中有操作--I)。_Ip和_I指向容器元素5时,(3)的条件满足。
(3)、因其处在无限循环for(;;)中,故在容器中从后往前找第一个非逆序(后面的元素不小于其紧挨的之前的元素*--I<*_lp)(3,5),此时_I指向3,_lp指向5。
(4)、对_I到最后一个元素之间的元素查询是否有大于_I所指向的元素(3),有!此时_J指向元素5大于3。如果没有,那么该for循环最后_I,_J指向同一元素3,同样结束该for循环。
(5)、交换_I,_J所指向的元素。得到容器{4532}
(6)、对于_lp和_L之间的元素重新按反序排列,原来为逆序532,现在重排为235,于是得到容易{4235} ,即是容器{3542}的下一个排列。
(7)、对于已经排成完全逆序的容器,如{5432},则先将其按反序重排为完全顺序{2345},然后返回false,因为其不存在下一个排列。
注意:在求容器的下一个排列时,总是要保证容器靠前的元素最小的不同排列,且如果得到完全逆序容器,则返回false,所以如果要求一个容器的全排列,应该先对该容器进行顺序排序,最后一点经过next_permutation()操作最后返回false后的容器为顺序的,应为该算法对完全逆序容器是先反序排列了之后再返回false的。