思路: 在数学中,一个集合所有子集个数为2的n次方
以3个字母为例,它的子集个数或组合有8种,非空子集个数有7种。
解题方法: 我们可以用2进制Bit位来标记集合中的某个元素是否被选中,1代表选中,0代表未选中。则字母a、b、c三个字母所组成的集合的所有子集可如下表示:
0 0 0–>空集
0 0 1–>[c]
0 1 0–>[b]
1 0 0–>[a]
0 1 1–>[b,c]
1 0 1–>[a,c]
1 1 0–>[a,b]
1 1 1–>[a,b,c]
此题有26个字母,它所有的组合有2的26次方,计算的结果为67108864种组合,通过下列代码,得到所有组合的具体内容
/**
* 有26个字母a-z,找出所有字母的组合,a、b、C、 ab、abc、a~z 都是一个组合(顺序无关)
*
* @author hf
*
*/
public class Blogs5 {
public static void main(String[] args) {
int n = 26;// 自定以数组的长度,即多少个字母
int[] arr = new int[n];
diGui(arr, 0, arr.length);
// System.out.println(count);//打印结果
}
// public static double count = 0;//统计组合数量
/**
* 递归全排列 得到数组存放二进制码的所有情况
*
* @param arr
* @param k
* @param end
*/
public static void diGui(int[] arr, int k, int end) {
if (k == end) {
// count++;//每一次排列都是一个组合
System.out.println(dayin(arr));
return;
}
for (int i = 0; i < 2; i++) {
arr[k] = i;
diGui(arr, k + 1, end);
}
}
/**
* 将数组上每一个位置上的二进制码,通过0消1转化的方式,得到字符串
* 0消:二进制码为0,说明这个字符串上没有对应的元素,故跳过循环
* 1转换:二进制码为1,则通过对应数组(下标值+'a')强制转换成相应的字母并连接的字符串中去
*
* @param arr
* @return
*/
public static StringBuffer dayin(int[] arr) {
StringBuffer sBuffer = new StringBuffer();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0) {
continue;
} else {
sBuffer.append((char) ('a' + i));
}
}
return sBuffer;
}
}