集合划分问题--贝尔数

来源:互联网 发布:iphone 照片 导入 mac 编辑:程序博客网 时间:2024/04/19 16:06

问题描述:
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,计算出n个元素的集合{1,2,, n }可以划分为多少个不同的非空子集。  

代码实现:

import java.util.Scanner;



/**
 * @author Administrator 集合划分
 * B(0) = 1,
 * B(n+1) = Sum(0,n) C(n,k)B(k). n = 1,2,...
 * 其中,Sum(0,n)表示对k从0到n求和,C(n,k) = n!/[k!(n-k)!] 
 */
public class SetManage {


/**
* @param n
* @param m
* @return
*/
int c(int n, int m) {
if (m > n / 2) {
m = n - m;
}
int a = 1, b = 1;
for (int i = n; i > n - m; i--) {
a *= i;
}
for (int i = 2; i <= m; i++) {
b *= i;
}
return a / b;
}


/**
* 贝尔数
* @param n
* @return
*/
int bell(int n) {
int t = 0;
if (n == 0) {
return 1;
} else {
for (int i = 0; i <= n - 1; i++)
t += c(n - 1, i) * bell(i);
}
return t;
}


/**
* @param args
*/
public static void main(String[] args) {
int n;
SetManage sm = new SetManage();
Scanner sc = new Scanner(System.in);
System.out.println("请输入集合的上限:");
n = sc.nextInt();
System.out.println(sm.bell(n));


}


}