Next_permutation:按照升序全排列
源码:
// TEMPLATE FUNCTION next_permutation
template<class _BidIt> inline
bool _Next_permutation(_BidIt _First, _BidIt _Last)
{ // permute and test for pure ascending, using operator<
_BidIt _Next = _Last;
if (_First == _Last || _First == --_Next)
return (false);
for (; ; )
{ // find rightmost element smaller than successor
_BidIt _Next1 = _Next;
if (_DEBUG_LT(*--_Next, *_Next1))//相邻两者两两比较,如果后者大于前者,则认为
//找到了需要排序的点,
{ // swap with rightmost element that's smaller, flip suffix
_BidIt _Mid = _Last;
for (; !_DEBUG_LT(*_Next, *--_Mid); );//然后寻找排序点后比当前排序点更大值
_STD iter_swap(_Next, _Mid);//将前者排序的点和后者第一组小的元素交换.这样
_STD reverse(_Next1, _Last);//逆排序
return (true);
}
if (_Next == _First)
{ // pure descending, flip all
_STD reverse(_First, _Last);
return (false);
}
}
}
函数的整个外循环就是从_Last开始往前找,直到找到两两相邻中前者较小的元素_i.然后进行内层循环扫描,寻找比当前相邻较小元素更大的元素_Mid.然后交换找到的元素_Mid与_Next.至此,_First-_Next这部分元素已经满足要求了.只是_Mid-_Last这段元素是_Mid-Last序列中的降序排列(为什么这里的元素是降序排列?因为经过外层循环两两比较和内层循环查找比_Next最大的元素并交换之后,如果不满足降序条件是不切实际的).
这里可以使用如下定理:
b > c
a > b
则a > b > c(即升序也就是_Next1-_Last降序).
需要记住的一点是,程序返回的是比_First-_Last中的更大(刚好更大)的序列.
这个函数似乎也在启示我们,在需要获取几个数的全排列,我们可以现将序列排序,然后利用这个函数来解决.
函数的最后一个判断_Next == _First,则说明容器的最大序列就是本身.但此时即使返回的false,容器的元素顺序也改变了.变成了最小序列.
Prev_permutation:与next_permutation相对.
// TEMPLATE FUNCTION prev_permutation
template<class _BidIt> inline
bool _Prev_permutation(_BidIt _First, _BidIt _Last)
{ // reverse permute and test for pure descending, using operator<
_BidIt _Next = _Last;
if (_First == _Last || _First == --_Next)
return (false);
for (; ; )
{ // find rightmost element not smaller than successor
_BidIt _Next1 = _Next;
if (_DEBUG_LT(*_Next1, *--_Next))
{ // swap with rightmost element that's not smaller, flip suffix
_BidIt _Mid = _Last;
for (; !_DEBUG_LT(*--_Mid, *_Next); )
;
_STD iter_swap(_Next, _Mid);
_STD reverse(_Next1, _Last);
return (true);
}
if (_Next == _First)
{ // pure ascending, flip all
_STD reverse(_First, _Last);
return (false);
}
}
}
有了前一个函数,后一个函数就简单多了.注意红色部分.
举例:
int main()
{
vector<int> vecInt;
vecInt.push_back( 1 );
vecInt.push_back( 2 );
vecInt.push_back( 3 );
vecInt.push_back( 4 );
while( next_permutation( vecInt.begin(),vecInt.end() ) )
{
cout<<"\n";
copy( vecInt.begin(),vecInt.end(),ostream_iterator<int>( cout," " ) );
}
cout<<"\nvecInt元a素?的?最?小?的?序ò列为a:";
copy( vecInt.begin(),vecInt.end(),ostream_iterator<int>( cout," " ) );
system( "pause" );
return 0;
}