/* * 將多個集合合併成沒有交集的集合。 給定一個字符串的集合,格式如:{aaa,bbb,ccc},{bbb,ddd},{eee,fff},{ggg},{ddd,hhh}要求將其中交集不爲空的集合合併,要求合併完成後的集合之間無交集, 例如上例應輸出{aaabbbcccdddhhh},{eeefff},{ggg}。 (1)請描述你解決這個問題的思路; (2)請給出主要的處理流程,算法,以及算法的複雜度; (3)請描述可能的改進。 解: 1.對字符集合進行依次編號,分別爲[0,1,2,3,4]。若是將{{aaa,bbb,ccc},{bbb,ddd},{eee,fff},{ggg},{ddd,hhh}}看作成二維數組,編號對應二維數組的下標。 初始化一個數組int father[] = {0,1,2,3,4};,表明其下標。 將字符串集合放到list<Set<String>>中集合resList 2.建立一個Map<String,List<Integer>>,key爲字符串,value爲字符串所在的編號。遍歷集合找出每一個字符串的編號,以下: aaa 0 bbb 0,1 ccc 0 ddd 1,4 eee 2 fff 2 ggg 3 hhh 4 3.合併,合併的時候將編號大的集合合併到小的集合裏面。方法是:遍歷map中的List<Integer>,更新father對應的下表,以下: aaa 0 {0,1,2,3,4} bbb 0 1 {0,0,2,3,4} ccc 0 {0,0,2,3,4} ddd 1 4 {0,0,2,3,0} eee 2 {0,0,2,3,0} fff 2 {0,0,2,3,0} ggg 3 {0,0,2,3,0} hhh 4 {0,0,2,3,0} 以後遍歷father數組,若是i!=faterh[i],則 Set<String> dest = resList.get(father[i]); Set<String> sour = resList.get(i); sour.addAll(dest); */ import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.Map; import java.util.HashMap; import java.util.Iterator; import java.util.Arrays; public class ShowDisjointSet{ private List<Set<String>> resList = new ArrayList<Set<String>>(); private int[] father; private int len; public static void main(String args[]){ String[] str0 = {"aaa","bbb","ccc"}; String[] str1 = {"bbb","ddd"}; String[] str2 = {"eee","fff"}; String[] str3 = {"ggg"}; String[] str4 = {"ddd","hhh"}; String[][] arr = {str0,str1,str2,str3,str4}; ShowDisjointSet obj = new ShowDisjointSet(); obj.getResList(arr); } // 1:並查集 public void getResList(String[][] arr){ len = arr.length; // 初始化resList for(String[] tmp:arr){ Set<String> set = new HashSet<String>(); set.addAll(Arrays.asList(tmp)); resList.add(set); } // 初始化數組 father = new int[len]; for(int i=0;i<len;i++){ father[i] = i; } Map<String,List<Integer>> map = getRes(arr); unionSet(map); System.out.println(resList); } // 2:遍歷集合 public Map<String,List<Integer>> getRes(String[][] arr){ Map<String,List<Integer>> map = new HashMap<String,List<Integer>>(); for(int i=0; i<len; i++){ for(String tmp:arr[i]){ if(!map.containsKey(tmp)){ List<Integer> list = new ArrayList<Integer>(); list.add(i); map.put(tmp,list); }else{ map.get(tmp).add(i); } } } return map; } // 3:合併集合 public void unionSet(Map<String,List<Integer>> map){ Iterator<Map.Entry<String,List<Integer>>> ite = map.entrySet().iterator(); while(ite.hasNext()){ Map.Entry<String,List<Integer>> entry = ite.next(); String key = entry.getKey(); List<Integer> value = entry.getValue(); unionHelp(value); System.out.println(key+":"+value); } System.out.println("the father array is "+ Arrays.toString(father)); for(int i=0; i<len; i++){ if(i != father[i]){ Set<String> dest = resList.get(father[i]); Set<String> sour = resList.get(i); dest.addAll(sour); } } for(int i=0; i<len; i++){ if(i != father[i]){ resList.get(i).clear(); } } } public void unionHelp(List<Integer> list){ int min = getFather(list.get(0)); int size = list.size(); for(int i=0; i<size; i++){ father[list.get(i)] = min; } } public int getFather(int index){ while(index!=father[index]){ index = father[index]; } return index; } }