1、问题描述

将多个集合合并成没有交集的集合。
给定一个字符串的集合,格式如:{aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh}要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应输出{aaa bbb ccc ddd hhh},{eee fff}, {ggg}。
(1)请描述你解决这个问题的思路;
(2)请给出主要的处理流程,算法,以及算法的复杂度
(3)请描述可能的改进。

2、分析

1. 假定每个集合编号为0,1,2,3...
    2. 创建一个hash_map,key为字符串,value为一个链表,链表节点为字符串所在集合的编号。遍历所有的集合,将字符串和对应的集合编号插入到hash_map中去。
    3. 创建一个长度等于集合个数的int数组,表示集合间的合并关系。例如,下标为5的元素值为3,表示将下标为5的集合合并到下标为3的集合中去。开始时将所有值都初始化为-1,表示集合间没有互相合并。在集合合并的过程中,我们将所有的字符串都合并到编号较小的集合中去。
    遍历第二步中生成的hash_map,对于每个value中的链表,首先找到最小的集合编号(有些集合已经被合并过,需要顺着合并关系数组找到合并后的集合编号),然后将链表中所有编号的集合都合并到编号最小的集合中(通过更改合并关系数组)。
    4.现在合并关系数组中值为-1的集合即为最终的集合,它的元素来源于所有直接或间接指向它的集合。
    0: {aaa bbb ccc}
    1: {bbb ddd}
    2: {eee fff}
    3: {ggg}
    4: {ddd hhh}
    生成的hash_map,和处理完每个值后的合并关系数组分别为
    aaa: 0           
    bbb: 0, 1        
    ccc: 0          
    ddd: 1, 4       
    eee: 2           
    fff: 2          
    ggg: 3           
    hhh: 4          
    所以合并完后有三个集合,第0,1,4个集合合并到了一起,
    第2,3个集合没有进行合并。

3、具体实现

class DisjointSetProblem {
int SIZE = 7;
int[] father;  
new ArrayList<Set<String>>();
   5:  
void main(String[] args) {
, };
, };
, };
, };
, };
, };
, };
  14:         String[][] strs = { str0, str1, str2, str3, str4, str5, str6 };
//change String[][] to List<Set>  
for (String[] str : strs) {
new HashSet<String>();
  19:             set.addAll(Arrays.asList(str));
  20:             resultList.add(set);
  21:         }
new DisjointSetProblem();
  23:         disjointSet.disjoin(strs);
  24:     }
  25:  
/*
     * 获取hashmap过程
     * */
void disjoin(String[][] strings) {
if (strings == null || strings.length < 2)
return;
  32:         initial();
// 获得hash_map:key为字符串,value为一个链表
  34:         Map<String, List<Integer>> map = storeInHashMap(strings);
// 并查集进行合并
  36:         union(map);
  37:     }
  38:  
void initial() {
int[SIZE];
int i = 0; i < SIZE; i++) {
  43:             father[i] = i;
  44:         }
  45:     }
  46:  
/* Map<k,v> 
     * key:String 
     * value:List<Integer>-in which sets the string shows up. 
     */
public Map<String, List<Integer>> storeInHashMap(String[][] strings) {
new HashMap<String, List<Integer>>();
int i = 0; i < SIZE; i++) {
for (String each : strings[i]) {
if (!map.containsKey(each)) {
new ArrayList<Integer>();
  57:                     list.add(i);
  58:                     map.put(each, list);
else {
  60:                     map.get(each).add(i);
  61:                 }
  62:             }
  63:         }
  64:  
// 打印出map
);
  67:         printMap(map);
return map;
  69:     }
  70:  
void printMap(Map<String, List<Integer>> map) {
// TODO Auto-generated method stub
  73:         Iterator<Map.Entry<String, List<Integer>>> iter = map.entrySet()
  74:                 .iterator();
while (iter.hasNext()) {
  76:             Map.Entry<String, List<Integer>> entry = iter.next();
  77:             String key = entry.getKey();
  78:             List<Integer> value = entry.getValue();
 + value);
  80:         }
  81:         System.out.println();
  82:     }
  83:  
/*
     * 对hashmap进行并查集合并操作
     * */
void union(Map<String, List<Integer>> map) {
  88:         Iterator<Map.Entry<String, List<Integer>>> it = map.entrySet()
  89:                 .iterator();
while (it.hasNext()) {
  91:             Map.Entry<String, List<Integer>> entry = it.next();
  92:             List<Integer> value = entry.getValue();
//the arrays whose indexes are in the same list should be merged to one set.             
  94:         }
// 打印出father父节点信息
);
  98:         printSetList(resultList);
//merge two sets  
int i = 0; i < SIZE; i++) {
if (i != father[i]) {
// set:无重复元素
 103:                 Set<String> dest = resultList.get(father[i]);
 104:                 Set<String> source = resultList.get(i);
 105:                 dest.addAll(source);
 106:             }
 107:         }
//clear a set which has been added.  
// 当B集合添加到A集合后,清空B集合
int i = 0; i < SIZE; i++) {
if (i != father[i]) {
 112:                 resultList.get(i).clear();
 113:             }
 114:         }
 + resultList);
 116:     }
 117:  
void unionHelp(List<Integer> list) {
//list[0] is the smaller.  
// 传过来的list参数已经排好序
int i = 0, size = list.size(); i < size; i++) {
//father[list.get(i)] = minFather;
 123:             unionHelp(list.get(0),list.get(i));
 124:         }
 125:     }
 126:  
// 路径压缩
int x) {
while (x != father[x]) {
 130:             x = father[x];
 131:         }
return x;
 133:     }    
 134:  
int[] fatherNode) {
// TODO Auto-generated method stub
int node : fatherNode)
);
 139:         System.out.println();
 140:     }
 141:  
void printSetList(List<Set<String>> list) {
// TODO Auto-generated method stub
);
int i = 0; i < SIZE; i++) {
);
 147:         }
 148:         System.out.println();
 149:     }
 150:  
//general union in disjoin set.But we overload it in this case.  
int y) {
if (father[x] != father[y]) {
int fx = getFather(x);
int fy = getFather(y);
//merge two arrays to the array that has a smaller index.  
if (fx < fy) {
 158:                 father[y] = fx;
else {
 160:                 father[x] = fy;
 161:             }
 162:         }
 163:     }
 164:     
 165: }

相关文章: