1、生成1~n的排列
include<stdio.h> #include<string.h> const int N=1e3+10; int a[N]; void print_permutation(int n,int *a,int cur) { int i,j; if(cur==n) /*遞歸邊界*/ { for(i=0;i<n;i++) printf("%d ",a[i]); printf("\n"); } else { for(i=1;i<=n;i++) /*嘗試在a[cur]中填各種整數i*/ { int ok=1; for(j=0;j<cur;j++) if(a[j]==i) /*如果i已經在a[0]~a[cur-1]出現過,則不能再選*/ { ok=0; break; } if(ok) { a[cur]=i; print_permutation(n,a,cur+1); /*遞歸調用*/ } } } } int main() { int n; while(~scanf("%d",&n)) print_permutation(n,a,0); return 0; } #include<stdio.h> #include<string.h> const int N=1e3+10; int a[N]; void print_permutation(int n,int *a,int cur) { int i,j; if(cur==n) /*遞歸邊界*/ { for(i=0;i<n;i++) printf("%d ",a[i]); printf("\n"); } else { for(i=1;i<=n;i++) /*嘗試在a[cur]中填各種整數i*/ { int ok=1; for(j=0;j<cur;j++) if(a[j]==i) /*如果i已經在a[0]~a[cur-1]出現過,則不能再選*/ { ok=0; break; } if(ok) { a[cur]=i; print_permutation(n,a,cur+1); /*遞歸調用*/ } } } } int main() { int n; while(~scanf("%d",&n)) print_permutation(n,a,0); return 0; }
2、生成可重集的排列
上面求排列的程序只適用於任意兩個元素均不相同的序列,如果要求有元素相同的序列的排列時,則需要對上面的程序進行修改。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int N=1e3+10; int a[N],p[N]; void print_permutation(int n,int *p,int *a,int cur) { int i,j; if(cur==n) { for(i=0;i<n;i++) printf("%d ",a[i]); printf("\n"); } else { for(i=0;i<n;i++) if(p[i]!=p[i-1]) { int c1=0,c2=0; for(j=0;j<cur;j++) if(a[j]==p[i]) c1++; for(j=0;j<n;j++) if(p[i]==p[j]) c2++; if(c1<c2) { a[cur]=p[i]; print_permutation(n,p,a,cur+1); } } } } int main() { int n,i; while(~scanf("%d",&n)) { for(i=0;i<n;i++) scanf("%d",&p[i]); sort(p,p+n); print_permutation(n,p,a,0); } return 0; } #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int N=1e3+10; int a[N],p[N]; void print_permutation(int n,int *p,int *a,int cur) { int i,j; if(cur==n) { for(i=0;i<n;i++) printf("%d ",a[i]); printf("\n"); } else { for(i=0;i<n;i++) if(p[i]!=p[i-1]) { int c1=0,c2=0; for(j=0;j<cur;j++) if(a[j]==p[i]) c1++; for(j=0;j<n;j++) if(p[i]==p[j]) c2++; if(c1<c2) { a[cur]=p[i]; print_permutation(n,p,a,cur+1); } } } } int main() { int n,i; while(~scanf("%d",&n)) { for(i=0;i<n;i++) scanf("%d",&p[i]); sort(p,p+n); print_permutation(n,p,a,0); } return 0; }
3、求下一個排列
枚舉所有排列的另一個方法是從字典序最小的排列開始,不停調用“求下一個排列”的過程。 如何求下一個排列呢?C++的STL中提供了一個庫函數next_permutation。
?#include<stdio.h> #include<algorithm> using namespace std; int main() { int n,i,p[10]; while(~scanf("%d",&n)) { for(i=0;i<n;i++) scanf("%d",&p[i]); sort(p,p+n); /*排序,得到p的最小排列*/ do { for(i=0;i<n;i++) printf("%d ",p[i]); /*輸出排列p*/ printf("\n"); }while(next_permutation(p,p+n)); /*求下一個排列*/ } return 0; } #include<stdio.h> #include<algorithm> using namespace std; int main() { int n,i,p[10]; while(~scanf("%d",&n)) { for(i=0;i<n;i++) scanf("%d",&p[i]); sort(p,p+n); /*排序,得到p的最小排列*/ do { for(i=0;i<n;i++) printf("%d ",p[i]); /*輸出排列p*/ printf("\n"); }while(next_permutation(p,p+n)); /*求下一個排列*/ } return 0; }