N个数取m个数的全排列非递归

来源:互联网 发布:降温软件排行第一 编辑:程序博客网 时间:2024/05/18 21:47

N个字符全排列的非递归实现http://blog.csdn.net/lin200753/article/details/27714987

N个字符全排列的递归实现http://blog.csdn.net/lin200753/article/details/27698233

这两篇是之前写的,采用递归和字典算法实现的。但它们都只是实An,n的输出即1...5,中取出5个数的排列。5*4*3*2*1.

但一般化就是从N个数取m个出来,每次不放回,输出它们的排列方式。

N个色子的组合输出http://blog.csdn.net/lin200753/article/details/27797391

从而也可以采用回溯法来解决上面的问题,不允许重复数字或字符的情况

应用回溯法产生排列a(n,m),设置一维数组arr,arr[i]在1-n之间取值,出现数字相同时就返回.当i<m-1时,则没有完整取完m个数,因此把i加1,并使a[i]=1.当i=m时输出一个结果.

当a[i]<n时,a[i]增1,当a[i]=n时回溯或调整.直到i=0时结束.


/* Note:Your choice is C IDE */#include "stdio.h"#include<malloc.h>void Print_arr_n(int arr[],int n){int i;for(i=0;i<n-1;i++)printf("%d,",arr[i]);printf("%d\n",arr[i]);}void QuanPaiLei(int n,int m){int count=0;int arr[100];int i,j=0;int flag=1;//用于判断数组中是否有重复的数,为1时没有,否则为0;i=0;arr[0]=1;while(1){flag=1;for(j=0;j<i;j++){//每次输出前都要,判断是否有重复;if(arr[i]==arr[j]){flag=0;break;}}if(flag==1&&i==m-1){Print_arr_n(arr,m);count++;}if(flag==1&&i<m-1){i++;arr[i]=1;////每个都要从1开始continue;}while(arr[i]==n)i--;if(i>=0)arr[i]++;elsebreak;}printf("count=%d\n",count);}void main(){    QuanPaiLei(4,2);}
1,21,31,42,12,32,43,13,23,44,14,24,3count=12             Press any key to continue

3,3

1,2,31,3,22,1,32,3,13,1,23,2,1count=6             Press any key to continue
_____________________________________________________________________________________

若为允许放回,即每个都是独立的,则只要把flag的判断去掉,通过一个宏开关可以进行控制

#include "stdio.h"#include<malloc.h>#define DUB_DULI 1//独立情况为1,非独立则为0void Print_arr_n(int arr[],int n){int i;for(i=0;i<n-1;i++)printf("%d,",arr[i]);printf("%d\n",arr[i]);}void QuanPaiLei(int n,int m){int count=0;int arr[100];int i,j=0;int flag=1;//用于判断数组中是否有重复的数,为1时没有,否则为0;i=0;arr[0]=1;while(1){flag=1;if(DUB_DULI==1){flag=1;}else{//每次输出前都要,判断是否有重复;for(j=0;j<i;j++){if(arr[i]==arr[j]){flag=0;break;}}}if(flag==1&&i==m-1){Print_arr_n(arr,m);count++;}if(flag==1&&i<m-1){i++;arr[i]=1;////每个都要从1开始continue;}while(arr[i]==n)i--;if(i>=0)arr[i]++;elsebreak;}printf("count=%d\n",count);}void main(){    QuanPaiLei(3,3);}

1,1,11,1,21,1,31,2,11,2,21,2,31,3,11,3,21,3,32,1,12,1,22,1,32,2,12,2,22,2,32,3,12,3,22,3,33,1,13,1,23,1,33,2,13,2,23,2,33,3,13,3,23,3,3count=27             Press any key to continue

转载请标明出处:blog.csdn.net/lin200753/article/details/27814395

0 0
原创粉丝点击