组合的生成

来源:互联网 发布:淘宝店铺被处罚扣分 编辑:程序博客网 时间:2024/04/30 06:18
/*组合的生成*/#include<stdio.h>#include<stdlib.h>void generate_i(int *c,int n,int r,int *i){int j;for(j=r;j>=1;j--){if(c[j]<(n-r+j)){break;}}*i=j;}void set_cj(int *c,int r,int i){int j;for(j=i+1;j<=r;j++){c[j]=c[j-1]+1;}}void print(int *c,int r){int x;printf("c ");for(x=1;x<=r;x++){printf("%d ",c[x]);}printf("\n\n");}void main(){int n,r,N,*c,x,i;printf("请输入n:");scanf("%d",&n);printf("请输入r:");scanf("%d",&r);c=(int*)malloc((r+1)*sizeof(int));//初始化cfor(x=0;x<=r;x++){c[x]=x;}print(c,r);//求出c(n,r)for(x=n,N=1;x>(n-r);x--){N*=x;}for(x=r;x>1;x--){N/=x;}//循环N-1次求出每次的组合for(x=0;x<N-1;x++){generate_i(c,n,r,&i);c[i]=c[i]+1;set_cj(c,r,i);print(c,r);}scanf("%d",&x);}



有时候我们需要组合作为一个程序模块——以C的角度来说,我们需要组合的生成作为一个.h文件和一个.c文件,需要的时候包含该.h文件就行。

所以我把上面的程序改写成如下形式:

首先是.h文件:

#ifndef COMBINATION_H#define COMBINATION_Htypedef enum{FIRST_TIME,NOT_FIRST_TIME}WHICH_TIME;int get_combination(WHICH_TIME which_time,int n,int r,int * res);#endif

下面是.c文件:

#include "combination.h"void get_i(int *c,int n,int r,int *i)  {      int j;      for(j=r;j>=1;j--){          if(c[j]<(n-r+j)){              break;          }      }      *i=j;  }  void set_cj(int *c,int r,int i)  {      int j;      for(j=i+1;j<=r;j++){          c[j]=c[j-1]+1;      }  }int get_combination(WHICH_TIME which_time,int n,int r,int * res){static int mn;static int mr;static int N;static int count=1;int i;if(r>n||n<0||r<0){return 0;}if(which_time==FIRST_TIME){mn=n;mr=r;for(i=1;i<=mr;i++){  res[i]=i;  }for(i=n,N=1;i>(mn-mr);i--){N*=i;}for(i=r;i>1;i--){N/=i;}return 1;}count++;if(count>N){return 0;}get_i(res,mn,mr,&i);res[i]=res[i]+1;set_cj(res,mr,i);return 1;}

下面是使用这个模块的示例:

#include<stdio.h>#include<stdlib.h>#include"combination.h"int main(void){int i;int n,r,*list;scanf("%d",&n);scanf("%d",&r);list=(int *)malloc(sizeof(int)*(r+1));if(get_combination(FIRST_TIME,n,r,list)){do{for(i=1;i<=r;i++){printf("%d ",list[i]);}printf("\n");}while(get_combination(NOT_FIRST_TIME,n,r,list));}scanf("%d",&i);return 1;}

如果你要使用这个模块,有几点需要注意:

1.你需要开辟一个(r+1)的Int数组空间用来接收结果,并且在你获得的结果里不要管第一项,也就是下标为0的那一项。

2.你需要指定是第一次调用还是之后的调用,即FIRST_TIME和NOT_FIRST_TIME

3.欢迎改写





原创粉丝点击