如果从N个数中取M个数进行组合,该怎么编程实现呢?
例如从1,2,3,4中选取两个数进行组合,得到下列组合结果:
1,2
1,3
1,4
2,3
2,4
3,4
这里编程我们考虑递归算法,两个数组,a存储给定数组,b存储组合的元素,算法的核心是从a中逆着取元素组成数组b.
程序如下:
#include<stdio.h>
#define N 4
#define M 2
//全局变量,a为给定数组,b为存储组合的数组
int a[N];
int b[M];
//函数声明
void comb(int,int);
void print();
//打印数组b
void print()
{
int i;
for(i=0;i<M;i++) {
printf("%d ",b[i]);
}
printf("\n");
}
//组合,递归方式
void comb(int n,int m)
{
int i;
if(m==0) {
print();
return;
} else {
for(i=n-1;i>=0;--i) {
b[m-1]=a[i];
comb(i,m-1);
}
}
}
int main()
{
int i;
for(i=0;i<N;i++)
a[i]=i+1;
comb(N,M);
return 0;
}
假设现在给定数组1,2,3,其全排列如下所示:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
编程时,同样,还是采用递归的方法。
#include <stdio.h>
#define N 3
int a[N]; //全局变量,数组
//函数声明
void perm(int); /*求数组的全排列 */
void print();
void swap(int, int);
//主函数
int main(){
int i;
for(i = 0; i < N; ++i){
a[i] = i + 1;
}
perm(0);
return 0;
}
//全排列函数
void perm(int offset){
int i, temp;
if(offset == N-1){ // BaseCase
print();
return;
}else{
for(i = offset;i < N; ++i){
swap(i, offset);//交换前缀
perm(offset + 1);//递归
swap(i, offset);//将前缀换回来,继续做前一次排列
}
}
}
//打印数组
void print(){
int i;
for(i = 0; i < N; ++i)
printf(" %d ",a[i]);
printf("\n");
}
//交换全局数组的两个指定元素
void swap(int i, int offset){
int temp;
temp = a[offset];
a[offset] = a[i];
a[i] = temp;
}
例如从N个数中取出M个数,进行全排列。
#include<stdio.h>
#define N 4
#define M 2
int a[N];
void print()
{
int i;
for(i=0;i<M;++i)
printf(" %d ",a[i]);
printf("\n");
}
void swap(int i,int j)
{
int tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
void perm(int offset)
{
int i;
if(offset==M) {
print();
return;
} else {
for(i=offset;i<N;i++) {
swap(i,offset);
perm(offset+1);
swap(i,offset);
}
}
}
int main()
{
int i;
for(i=0;i<N;i++)
a[i]=i+1;
perm(0);
}
原文:http://my.oschina.net/zzw922cn/blog/520225