7.2.1 生成1~n的排列
这就是递归枚举啦~
#include<stdio.h> int num[20],n; void Print(int n,int *a,int cur) { int i,j,flag; if(cur == n+1)//递归边界 { for( i = 1; i < cur; i ++) printf("%d ",a[i]); printf(" "); } else { for( i = 1; i <= n; i ++) { flag = 1; for( j = 1; j < cur; j ++) if(a[j] == i)//如果i已经在a[1..cur-1]出现过,则舍弃 flag = 0; if(flag) { a[j] = i; Print(n,a,cur+1);//递归调用 } } } } int main() { scanf("%d",&n); Print(n,num,1); return 0; }
7.2.2生成可重集的排列(默认升序)
输入数组,并按字典序输出数组各元素的全排列
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int num[4]={0,1,2,3}; int a[4]; void A(int *a,int ans) { int i,ans1,ans2,j; if(ans == 4) { for(i = 1; i <= 3; i ++) printf("%d ",a[i]); printf(" "); } else { for(i = 1; i <= 3; i ++) { if(num[i]!=num[i-1])//排除重复输出排列的情况 { ans1 = ans2 = 0; for(j = 1; j < ans; j ++)if(a[j]==num[i])ans1++; for(j = 1; j < 4; j ++)if(num[i]==num[j])ans2++; if(ans1<ans2) { a[ans] = num[i]; A(a,ans+1); } } } } return; } int main() { A(a,1); return 0; }
7.2.3 解答树(额,关于这个知识点的学习,只能说自己了解了一下,具体怎么实现,以后遇到再学习)
7.2.4 下一个排列
利用了c++的stl里的next_permutation(permutation的中文意思是排列),这样就将枚举所有排列的方式扩展为两种啦,一种是之前学习的递归枚举,这种就是从字典序最小的开始,不停的求“下一个排列的过程”
#include<stdio.h> #include<algorithm> using namespace std; int main() { int num[4]={0,3,2,1}; int i; sort(num+1,num+1+3); do { for(i = 1; i <= 3; i ++) printf("%d ",num[i]); printf(" "); } while(next_permutation(num+1,num+1+3)); return 0; }