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]++;
else
break;
}
printf("count=%d\n",count);
}
void main()
{
QuanPaiLei(4,2);
}
1,2
1,3
1,4
2,1
2,3
2,4
3,1
3,2
3,4
4,1
4,2
4,3
count=12
Press any key to continue
3,3
1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1
count=6
Press any key to continue
_____________________________________________________________________________________
若为允许放回,即每个都是独立的,则只要把flag的判断去掉,通过一个宏开关可以进行控制
#include "stdio.h"
#include<malloc.h>
#define DUB_DULI 1//独立情况为1,非独立则为0
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;
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]++;
else
break;
}
printf("count=%d\n",count);
}
void main()
{
QuanPaiLei(3,3);
}
1,1,1
1,1,2
1,1,3
1,2,1
1,2,2
1,2,3
1,3,1
1,3,2
1,3,3
2,1,1
2,1,2
2,1,3
2,2,1
2,2,2
2,2,3
2,3,1
2,3,2
2,3,3
3,1,1
3,1,2
3,1,3
3,2,1
3,2,2
3,2,3
3,3,1
3,3,2
3,3,3
count=27
Press any key to continue
转载请标明出处:blog.csdn.net/lin200753/article/details/27814395