stl提供了兩個用來計算排列組合關係的演算法,分別是next_permutation和prev_permutation。首先我們必須了解什麼是「下乙個」排列組合,什麼是「前乙個」排列組合。考慮三個字元所組成的序列。
這個序列有六個可能的排列組合:abc,acb,bac,bca,cab,cba。這些排列組合根據less-than操作符做字典順序(lexicographical)
的排序。也就是說,abc名列第一,因為每乙個元素都小於其後的元素。acb是次乙個排列組合,因為它是固定了a(序列內最小元素)之後所做的新組合。
同樣道理,那些固定b(序列中次小元素)而做的排列組合,在次序上將先於那些固定c而做的排列組合。以bac和bca為例,bac在bca之前,因為次序ac小於序列ca。面對bca,我們可以說其前乙個排列組合是bac,而其後乙個排列組合是cab。序列abc沒有「前乙個」排列組合,cba沒有「後乙個」排列組合。
next_permutation()會取得[first,last)所標示之序列的下乙個排列組合,如果沒有下乙個排列組合,便返回false;否則返回true。這個演算法有兩個版本。版本一使用元素型別所提供的less-than操作符來決定下乙個排列組合,版本二則是以仿函式comp來決定。
演算法思想:
1.首先從最尾端開始往前尋找兩個相鄰元素,令第一元素為*i,第二元素為*ii,且滿足*i
2.找到這樣一組相鄰元素後,再從最尾端開始往前檢驗,找出第乙個大於*i的元素,令為*j,將i,j元素對調(swap)。
3.再將ii之後的所有元素顛倒(reverse)排序。
舉個例項,假設有序列,下圖便是套用上述演演算法則,一步一步獲得「下乙個」排列組合。圖中只框出那符合「一元素為*i,第二元素為*ii,且滿足*i
以下便是版本一的實現細節。版本二相當類似,就不列出來了。
1 template2簡單應用輸出序列字典序的全排列。bool
next_permutation(bidrectionaliterator first,bidrectionaliterator last)323
if(i == first) /*
進行至最前面了
*/2428}
29 }
[**實現]
1 #include2 #include3拓展1.能否直接算出集合的第n個排列?using
namespace
std;
4int
main()5;
7 sort(ans,ans+4); /*
這個sort可以不用,因為已經排好序*/8
do/*
注意這步,如果是while迴圈,則需要提前輸出*/9
while(next_permutation(ans,ans+4
));14
return0;
15 }
舉例說明:如7個數的集合為,要求出第n=1654個排列。
(1654 / 6!)取整得2,確定第1位為3(從0開始計數),剩下的6個數,求第1654 % 6!=214個序列;
(214 / 5!)取整得1,確定第2位為2,剩下5個數,求第214 % 5!=94個序列;
(94 / 4!)取整得3,確定第3位為6,剩下4個數,求第94 % 4!=22個序列;
(22 / 3!)取整得3,確定第4位為7,剩下3個數,求第22 % 3!=4個序列;
(4 / 2!)得2,確定第5為5,剩下2個數;由於4 % 2!=0,故第6位和第7位為增序<1 4>;
因此所有排列為:3267514。
[**實現]
1 #include2 #include32. 給定一種排列,如何算出這是第幾個排列呢?using
namespace
std;
4int
main()5;
7 sort(ans,ans+7); /*
同上可以不用sort */8
int n=0; 9
do//
注意這步,如果是while迴圈,則需要提前輸出
1018 n++;
19 }while(next_permutation(ans,ans+7
));20
return0;
21 }
和前乙個問題的推導過程相反。例如3267514:
後6位的全排列為6!,3為中第2個元素(從0開始計數),故2*720=1440;
後5位的全排列為5!,2為中第1個元素,故1*5!=120;
後4位的全排列為4!,6為中第3個元素,故3*4!=72;
後3位的全排列為3!,7為中第3個元素,故3*3!=18;
後2位的全排列為2!,5為中第2個元素,故2*2!=4;
最後2位為增序,因此計數0,求和得:1440+120+72+18+4=1654
這個的**實現,可以用乙個陣列a儲存3267514,然後while呼叫next_permutation(),用n計數,每次與陣列a比較,相等則輸出n;
stl演算法 next permutation剖析
在標準庫演算法中,next permutation應用在數列操作上比較廣泛.這個函式可以計算一組資料的全排列.但是怎麼用,原理如何,我做了簡單的剖析.首先檢視stl中相關資訊.函式原型 template boolnext permutation bidirectionaliterator first...
next permutation原理剖析
最近刷leetcode的時候遇見next permutation這道題,感覺挺有意思的乙個題目,遞迴的方法是較簡單並且容易想到的,在網上搜了其餘的解法,就是std next permutation非遞迴解法,但是讓人不是很舒服的就是關於原理的部分,千篇一律的都是摘抄 stl原始碼剖析 也就是這樣的。...
演算法 Next Permutation問題》
此問題描述如下 給定乙個陣列,首先從後向前找出最長的遞減序列的前乙個元素,比如陣列中,從後向前最長遞減序列是,這個序列的前乙個元素就是4,然後再遞減序列中找到最後乙個比這個數 4 大的數字 就是5 然後將5與4交換,得到新的陣列,然後將交換過後的遞減序列進行翻轉,最後得到的結果就是。如果陣列單調遞減...