集合可划分的划法

2019-01-19  本文已影响9人  雨中漫步的北极熊
集合划分的总划法

题目:
n个元素的集合{1,2,.,n }可以划分为若干个非空子集。

例如,当n=4 时,集合{1,2,3,4}可以划分为15个不同的非空子集如下:
{1},{2},{3},{4}}, {{1,2},{3},{4}},
{{1,3},{2},{4}}, {{1,4},{2},{3}},
{{2,3},{1},{4}}, {{2,4},{1},{3}},
{{3,4},{1},{2}}, {{1,2},{3,4}},
{{1,3},{2,4}}, {{1,4},{2,3}},
{{1,2,3},{4}}, {{1,2,4},{3}},
{{1,3,4},{2}}, {{2,3,4},{1}},
{{1,2,3,4}}
设计出一个算法计算出n个集合可以划分的总数


思路分析:假设把集合划分为3个子集
那么加入第n个数是一个子集那么和f(n-1,2)组成f(n,3)的一种情况,
另外一种情况是往f(n-1,3)中的任意一个子集中插入。
所以f(n,m) = f(n-1,m-1)+m*f(n-1,m)

代码如下

public static void main(String[] args) {
    int count =0;
    int n=16;
    for(int i=1;i<=n;i++){
      count = count + getPartitionNum(n, i);
    }
    System.out.println("集合数量为"+ n + "可划分的子集组成等于全集的划法有 " + count);
  }

  /**
   * 划分的个数
   * @param n 总数量
   * @param m 划分的子集个数
   * @return
   */
public static int getPartitionNum(int n,int m){
    if(n<m){
      return 0;
    }
    if(n==1 || m==1 || n==m){
      return 1;
    }else{
      return getPartitionNum(n-1, m-1) + m*getPartitionNum(n-1, m);
    }
  }

运行结果:
集合数量为16可划分的子集组成等于全集的划法有 1890207555


上一篇下一篇

猜你喜欢

热点阅读