1、next_permutation() 。
next_permutation()会取得[first,last)所标示之序列的下一个排列组合。如果没有下一个组合,便返回为false;否则,当前序列被排序成当前序列的下一个序列并且返回为true。
算法实现:
template <class _BidirectionalIter, class _Compare>
bool __next_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
_Compare __comp) {
_STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
if (__first == __last)
return false;
_BidirectionalIter __i = __first;
++__i;
if (__i == __last) //只有一个元素,只有一个排列,不存在下一个排列,返回为false
return false;
__i = __last;
--__i; //i指向最后一个元素
for(;;) {
_BidirectionalIter __ii = __i; //ii的指向范围为从序列的最后一个元素到顺数第二个元素
--__i;//i为ii前面一个元素
if (__comp(*__i, *__ii)) {
_STLP_VERBOSE_ASSERT(!__comp(*__ii, *__i), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
_BidirectionalIter __j = __last;
while (!__comp(*__i, *--__j)) {}//j从最后一个元素向前迭带,直到 *__i<*__j
iter_swap(__i, __j); //交换__i与__j所指向的元素
reverse(__ii, __last); //ii之后的元素反转
return true; //返回为true,结束算法
}
if (__i == __first) { //当前序列就是最小序列,不存在下一序列
reverse(__first, __last); //序列间的元素全部反转
return false; //返回为false,结束算法
}
}
#if defined (_STLP_NEED_UNREACHABLE_RETURN)
return false;
#endif
}
测试代码:
template<typename T>
void traverseEle(const std::vector<T> array)
{
for(auto it=array.begin();it!=array.end();++it)
std::cout<<*it<<"\t";
std::cout<<std::endl;
}
//测试函数
int main()
{
std::vector<char> charArray={'a','b','c','d','e'};
std::cout<<"before next_permutation:\n";
traverseEle(charArray);
std::next_permutation(charArray.begin(),charArray.end());
std::cout<<"before next_permutation:\n";
traverseEle(charArray);
}
执行结果:
2、prev_permutation()。取得当前序列的前一序列,若存在,则将当前序列置为当前序列的下一序列;否则,返回为false。
算法实现:
template <class _BidirectionalIter, class _Compare>
bool __prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last,
_Compare __comp) {
if (__first == __last)
return false;
_BidirectionalIter __i = __first;
++__i;
if (__i == __last)
return false;
__i = __last;
--__i;
for(;;) {
_BidirectionalIter __ii = __i;
--__i;
if (__comp(*__ii, *__i)) { //与next_permutation的第一处差别
_STLP_VERBOSE_ASSERT(!__comp(*__i, *__ii), _StlMsg_INVALID_STRICT_WEAK_PREDICATE)
_BidirectionalIter __j = __last;
while (!__comp(*--__j, *__i)) {}//与next_permutation的第二处差别
iter_swap(__i, __j);
reverse(__ii, __last);
return true;
}
if (__i == __first) {
reverse(__first, __last);
return false;
}
}
#if defined (_STLP_NEED_UNREACHABLE_RETURN)
return false;
#endif
}
测试代码:
template<typename T>
void traverseEle(const std::vector<T> array)
{
for(auto it=array.begin();it!=array.end();++it)
std::cout<<*it<<"\t";
std::cout<<std::endl;
}
//测试函数
int main()
{
std::vector<char> charArray={'a','b','c','d','e'};
std::cout<<"before next_permutation:\n";
traverseEle(charArray);
std::next_permutation(charArray.begin(),charArray.end());
std::cout<<"after next_permutation:\n";
traverseEle(charArray);
std::prev_permutation(charArray.begin(),charArray.end());
std::cout<<"after prev_permutation:\n";
traverseEle(charArray);
}
运行结果: