zoukankan      html  css  js  c++  java
  • 面试题: 已知一个含有n个不同元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的)

    TX面试题2: 已知一个含有n个元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的)

    题目分析, 为了便于说明,不妨将问题简化一下:

        已知一个盒子中有n个不同的球,分别标记为{a1,a2,...,an},现在需要从中取出其中任意k个球,求给出各种组合。

    首先,从组合数学的角度,我们可以知道本问题是一个典型的不放回组合问题,总的个数为 c(n,k).

    对于{a1,a2,...,an}中某一个元素 ai是否出现在k元子集中可以把问题分为如下两个子问题。

    (1) 如果ai出现在k元子集中,那么需要在剩下的 n-1个球中选出 k-1个球

    (2) 如果ai没有出现在k元子集中,那么需要在剩下的n-1个球中选出k个球

    既有: c(n,k) = c(n-1,k-1) + c(n-1,k)

    在有该理论的基础上,我们现在的目标就是利用递归调用,当取出的球的个数满足k,则将结果打印即可。

    为了好说明,我们将本问题再次简化一下, 如果已知n元素为连续集合[1,n], 那么递归程序为:

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 #define N 1000
     5 int a[N]={0}; // 用于存储选中的元素 
     6 int final_k;  // 用于记录k元子集的大小
     7  
     8 /***********************************
     9  * combination 函数中仅使用了a数组,而没有使用辅助数组,
    10  * 这是由于默认原始 N元集合为 {1,2,...,n}。 
    11 ************************************/
    12 void combination(int a[],int n,int k)
    13 {
    14      for(int i=n;i>=k;i--)
    15      {
    16          a[k] = i;
    17          if(k>1)
    18            combination(a,i-1,k-1);  // 不足final_k个元素,递归选取 
    19          else
    20          {
    21              for(int j=a[0];j>0;--j)  // 取出足够多球,打印之 
    22                  printf("%d ",a[j]);
    23              printf("
    ");
    24          }
    25      }
    26 }
    27 
    28 int main()
    29 {
    30     int n,k;
    31     printf("please input n and k: 
    ");
    32     scanf("%d%d",&n,&k);
    33     final_k =k;   
    34     combination(a,n,k);
    35     return 0;
    36 }

    如果是非连续的n个数呢,那么在combination中需要用到辅助数组了:

    tips: 由于LZ我有点懒,所以在输入n个数的时候,默认是不同的数,并没有判断是否有相同的元素。如果大伙儿想去重,请自行添加!

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 #define N 1000
     5 int a[N]={0};    // 原N元素集合 
     6 int b[N]={0};    // 辅助数组,用于存储当前选取的元素,便于打印 
     7 int final_k;     // 用于记录k元素子集是否满足 
     8 
     9 void combination(int a[],int n,int k)
    10 {
    11      for(int i=n;i>=k;i--)  // 由于是求k元素的组合,所以默认首元素的可能按照数组中顺序有n-k种 
    12      {
    13          b[k] = a[i];  // 将a[i] 放入到数组b中记录 
    14          if(k>1)       // 取出的个数不足final_k个 
    15            combination(a,i-1,k-1); 
    16          else          // 取出足够个数的球,打印结果 
    17          {
    18              for(int j=final_k;j>0;--j)
    19                  printf("%d ",b[j]);
    20              printf("
    ");
    21          }
    22      }
    23 }
    24 
    25 int main()
    26 {
    27     int a[N]={0};
    28     int n,k;
    29     printf("please input n and k: 
    ");
    30     scanf("%d%d",&n,&k);
    31     for(int i=1;i<=n;i++) scanf("%d",&a[i]);  //输入n个不同的元素
    32     final_k =k;   
    33     combination(a,n,k);
    34     system("pause");
    35     return 0;
    36 }
    random sequence

     转载请注明出处:http://www.cnblogs.com/double-win 

  • 相关阅读:
    MySQL事件(定时任务)
    MySQL存储过程
    WebSocket小记
    Python计算给定日期位于当年第几周
    报错解决——Failed building wheel for kenlm
    计算机基础系列之压缩算法
    计算机基础系列之内存、磁盘、二进制
    计算机基础系列之CPU
    常用正则表达大全
    报错解决——TypeError: LoadLibrary() argument 1 must be str, not None
  • 原文地址:https://www.cnblogs.com/double-win/p/3653004.html
Copyright © 2011-2022 走看看