/*=====================================
数的组合问题。从1,2,…,n中取出m个数,将所有组合按照字典顺序列出。
如n=3,m=2时,输出:
1 2
1 3
2 3
这里只考虑从互不相同的n个数当中选择m个的情况。
我的思路:
这里采用的思路和上回解决递归生成全排列的思路差不多。
从a数组的n个数当中选m个到ans数组。
每一次选择一个数到ans[i]时都在a数组中扫描并依次选择所有的可能。
但是这里扫描的范围是从ans[i-1]在a中的下标k的下一个开始,一直扫描到n-(m-i-1)的前一个位置为止。
这个范围是ans[i]的可能选择的范围。(后面还要选一部分才凑够m个数,故不能扫描到a数组的末尾。)
======================================*/
![]()
1 #include<stdio.h>
2 int count=0;
3 void fun(int a[],int n,int m,int i,int k,int ans[]);
4 //原始数组a[],从a数组的n个数当中选m个数,结果放在ans数组。
5 //i表示当前要选取第i个数。i从0开始。k表示上一次选取的数在a数组当中的下标。
6 //最开始时k==-1,表示还没选数据。
7 int main()
8 {
9 int n,m,a[30],ans[30],i;
10 freopen("5.out","w",stdout);
11 scanf("%d%d",&n,&m);
12 for(i=0;i<n;i++)
13 {
14 //scanf("%d",&a[i]);
15 a[i]=i+1;
16 }
17 fun(a,n,m,0,-1,ans);
18 printf("%d\n",count);
19 return 0;
20 }
21 void fun(int a[],int n,int m,int i,int k,int ans[])
22 //原始数组a[],从a数组的n个数当中选m个数,结果放在ans数组。
23 //i表示当前要选取第i个数。i从0开始计数。k表示上一次选取的数在a数组当中的下标。
24 //最开始时k==-1,表示还没选数据。
25 {
26 int j;
27 if(i==m)
28 {
29 for(j=0;j<m;j++) printf("%d ",ans[j]);
30 printf("\n");
31 count++;
32 return ;
33 }
34 else
35 {
36 for(j=k+1;j<n-(m-i-1);j++)//从第k+1个开始,尝试选择第i个数。(注意:i从0开始计算)
37 {
38 ans[i]=a[j];
39 fun(a,n,m,i+1,j,ans);
40 }
41 }
42 }
View Code