兩個(gè)函數(shù)類(lèi)似,重點(diǎn)介紹next_permutation.
template <class BidirectionalIterator>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last );
template <class BidirectionalIterator, class Compare>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last, Compare comp);
簡(jiǎn)介:得到下一個(gè)排列組合
默認(rèn)是按字典序,比如abc->acb->bac->bca->cab->cba
算法描述:
1、從尾部開(kāi)始往前尋找兩個(gè)相鄰的元素
第1個(gè)元素i,第2個(gè)元素j(從前往后數(shù)的),且i<j
2、再?gòu)奈餐罢业谝粋€(gè)大于i的元素k。將i、k對(duì)調(diào)
3、[j,last)范圍的元素置逆(顛倒排列)
運(yùn)行過(guò)程:
next: 01234
-> i=3,j=4
-> k=4,對(duì)調(diào)后01243
-> j指向最后一個(gè)元素,故結(jié)果為01243
next: 01243
-> i=2,j=4
-> k=3,對(duì)調(diào)后01342
-> j指向4,顛倒后為01324 即結(jié)果
...
next: 01432
-> i=1,j=4
-> k=2,對(duì)調(diào)后02431
-> j指向4,顛倒02134
按默認(rèn)字典序的內(nèi)部實(shí)現(xiàn)(帶仿函數(shù)的類(lèi)似):
#include <algorithm>
#include <iostream>
template<typename BidirectionalIterator>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last)
{
// 空區(qū)間
if(first == last)
return false;
BidirectionalIterator i = first;
++i;
// 只有一個(gè)元素
if(i == last)
return false;
// i指向尾部
i = last;
--i;
for (;;)
{
// i是j的上一個(gè)元素
BidirectionalIterator j = i;
--i;
if(*i < *j)
{
// 由尾部往前找到第一個(gè)比*i大的元素,并交換i,k
BidirectionalIterator k = last;
while(!(*i < *--k))
;
std::iter_swap(i, k);
// 將[j,last)的元素逆向重排
std::reverse(j, last);
return true;
}
// 到最前面了
if(i == first)
{
std::reverse(first, last);
return false;
}
}
}
int main()
{
int arr[] = {1, 2, 3};
do
{
std::cout<<arr[0]<<" "<<arr[1]<<" "<<arr[2]<<std::endl;
} while (next_permutation(arr, arr + 3));
prev_permutation()
// 到最前面的時(shí)候數(shù)組被reverse了
std::cout<<"last status: ";
std::cout<<arr[0]<<" "<<arr[1]<<" "<<arr[2]<<std::endl;
return 0;
}
prev_permutation與next_permutation不同之處就是
算法第一步:從尾部開(kāi)始往前尋找兩個(gè)相鄰的元素
第1個(gè)元素i,第2個(gè)元素j(從前往后數(shù)的),且i>j(next_permutation條件是i<j)