1,遞迴的全排列演算法
以abcd為例:
對於abcd,首先以第一位的字元分為四類:
(1)以a為第一位 abcd 固定a的位置,a後面跟著bcd的全排列
(2)以b為第一位 bacd (即交換第乙個字元a和b的位置),固定b的位置,b後面跟著acd的全排列
(3)以c為第一位 cbad (即交換第乙個字元a和c的位置),固定c的位置,c後面跟著bad的全排列
(4)以d為第一位 dbca (即交換第乙個字元a和d的位置),固定d的位置,d後面跟著bca的全排列
同樣的,對於(1)中bcd、(2)中的acd、(3)中的bad、(4)中的的bca的全排列,分別按照上面的形式遞迴求解。
**如下:
#include using namespace std;
templatevoid permutation(t array, int start, int end)
(右邊的數從右至左是遞增的,因此k是所有大於pj的數字中序號最大者)
3)對換pj,pk
4)再將pj+1......pk-1pkpk+1......pn倒轉得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,這就是排列p的下乙個排列。
舉個栗子:
1)從右端數字1開始,找到第乙個比相鄰的右邊小的數字,這個數字為3,記下3在數列中的位置 j=1(最左邊從0開始數)
2)找出3右邊的數字中,第乙個比3大的數字,這個數為4,記下這個數的位置 k=3
3)交換位置 j 的數字(3)和位置k 的數字(4),數列變為24531
4)反轉位置 j後面的數列(531),最終數列變為24135
24135即為原數列23541的下乙個字典序排列。
注意,如果原始序列為54321,已經為最大排列,那麼按照上面的方法,是找不到下乙個字典序的排列的。
所以,首先要對原始序列進行預處理,有兩種方法:
方法1,利用快速排序將原始序列按公升序排序,這樣就得到最小的排列pmin
方法2,判斷原始序列是不是最大排列pmax,若是,反轉pmax,使其成為pmin
實現**:
//交換陣列s中下標為x和y的兩個元素值
swap(char *s,int x, int y)
//反轉序列
reverse(char *s,int x, int y)
s[start]=s[end];
while(start=s[start]中的等號是為了避免序列中有重複的字元而導致的重複的排列
while(start>0&&s[start-1]>=s[start])
if(start==0)
return false;
while(end>start-1&&s[start-1]>=s[end])
swap(s,start-1,end);
reverse(s,start,len-1);
return true;
}void permutation(char *s,int len){
//快速排序,使原序列為最小乙個排列pmin
qsort(s,0,len-1);
/*//也可以不使用qsort對原序列進行排序,首先判斷原序列是否是最大的排列pmax,如果是的話,反轉原序列
int boolvalue=0;
for(int i=0;i
如果不想自己寫全排列的**的話,可以直接使用c++的stl中的函式next_permutation. 它的作用是判斷乙個序列,若存在下乙個字典序排列,那麼就返回true並產生這個排列,否則返回false。
#include #include using namespace std;
template void permutation(bidirectionaliterator array, int len)
{ sort(array, array + len);
do{
for(int i = 0; i < len; ++i){
cout<
參考文章:
全排列演算法 遞迴 字典序實現(Java)
全排列 從n個不同元素中任取m m n 個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的乙個排列。當m n時所有的排列情況叫全排列。例如 1 2 3三個元素的全排列為 解法1 遞迴 如下圖 要對1 2 3 4進行排序,第乙個位置上的元素有四種可能 1或2或3或4,假如已經確定了第乙...
全排列 方法 全排列函式和遞迴和字典序
給你乙個字串,按字典序從小到大輸出這個字串的全排列 乙個由小寫字母組成的長度小於等於8的不含重複字元的字串 按字典序從小到大輸出這個字串的全排列 abcabc acbbac bcacab cbanext permutation函式 組合數學中經常用到排列,這裡介紹乙個計算序列全排列的函式 next ...
全排列演算法的字典序排列
之前在中描述了全排列演算法的遞迴解法,這裡再說一種演算法 字典序排列。字典序排列就是按照字典a z,1 9的順序給出字串的順序全排列,例如abc的全排列就是從abc一直排到cba。那麼給定乙個字串,怎麼找出恰好大於該字串的下乙個排列呢?我們考慮如下的步驟 1 假設字串為p1p2 pn,我們從後往前尋...