思路:對於一個集合的元素來說,它要麼在這個子集裏面(1),要麼不在子集(0),就像下面這樣 {1,2},它的所有子集有 {},{1},{2},{1,2},翻譯成在與不在的意思就是:對於空集,一個元素都沒有,就是 00 ,只有2,就是 01,只有1就是 10,有1有2 ,就是 11,所以,要是能夠將集合變成數組,然後和相應 1、0組成數組一一對應成哪兒有1,那個就放在一個子集裏面,非常奇妙的解法!
import java.util.Set;
import java.util.TreeSet;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
public class SubSet{
public void init(int n){
for (int i=0;i<n ;i++ ) {
strSet.add(String.valueOf(i));
}
}
Set<String> strSet=new TreeSet<String>();
Set<Set<String>> subSet=new HashSet<Set<String>>();
public static void main(String[] args) {
SubSet ss=new SubSet();
ss.init(3);
// ss.getSubSet();
ss.getSubSet2(ss.strSet);
ss.myprint(ss.subSet);
}
public void myprint(Set<Set<String>> subSet){
for (Set<String> s:subSet ) {
System.out.println(s);
}
}
//解法2
public void getSubSet2(Set<String> strSet){
int total=strSet.size();
Object[] str=strSet.toArray();
//左移的性質,恰好是2的N次方
for (int i=0;i<(1<<total) ; i++) {
Set<String> temp=new TreeSet<String>();
for (int j=0;j<total ;j++ ) {
//需要遍歷整個組的下標,因此每次都需要將1左移j位
//而按位與運算則會只輸出都是1
//在這裏 i是說我要那幾位數,這幾位數是一個子集,然後j就遍歷整個數組,找到這幾位
if ((i & (1<<j))!=0) {
temp.add(str[j].toString());
}
}
subSet.add(temp);
}
}
//解法1
public void getSubSet(){
int total=strSet.size();
Object[] str=strSet.toArray();
//數學知識,一個集合的所有子集的個數是2的N次方,N是集合元素的個數
for (int i=0;i<Math.pow(2,total);i++ ) {
String str1=Integer.toBinaryString(i);
//java裏面的Integer.toBinaryString()會把二進制前的0給去掉,爲了一一對應,當然的補起來
while(str1.length()<total){
str1="0"+str1;
}
char[]ch=str1.toCharArray();
Set<String> temp=new TreeSet<String>();
for(int j=0;j<ch.length;j++){
if (ch[j]=='1') {
temp.add(str[j].toString());
}
}
subSet.add(temp);
}
}
}