我有不同的名字集。每组包含不同数量的字符串。我想知道哪个集合与哪个集合相交。我写了以下算法(未经测试)
//initial structure key= set name, value = actual set
Map<String, Set<String>> namedSets = new LinkedHashMap<String, Set<String>>();
//get a list of all sets
List<Set<String>> sets = new ArrayList<Set<String>>(namedSets.values());
List<String> names = new ArrayList<String>(namedSets.keySet());
while (!sets.isEmpty()){
Set<String> examinedSet = sets.remove(0); //remove it because it will be checked sortly.
String name = names.remove(0); //remove its name too.
//check it with remaining sets
for (Set<String> set : sets){
//there are common elements inside the two sets,
if (!Collections.disjoint(examinedSet, set)
addIntersection(name, names.get(names.indexOf(set)));
}
public void addIntersection(name, intersectedName){
if (conflictedSets.containsKey(name){
conflictedSets.get(name).add(intersectedName);
}else{
List<String> intersectedNames = new ArrayList<String>();
intersectedNames.add(intersectedName);
conflictedSets.put(name, intersectedNames);
}
}
我不喜欢我必须做这个嵌套循环的事实,尽管对于它的迭代它完成了一个循环,因为已检查的名称从列表中删除。有更有效的方法吗?我的问题是,我不想检查它们是否相交,但是哪一个是相交的。有更高效的算法吗? }
答案 0 :(得分:0)
这样的事情怎么样?对不起,Java8并不算太多。但是,我们的想法是将所有内容放入哈希表中,然后将包含至少1个共同元素的元素视为相交。我测试了它,它的工作原理。由于内存的原因,这不能很好地扩展,因此如果您的集合包含数百万条目,那么它可能不是最佳选择。但是它在O(N)时间内运行,N是所有集合中的条目数。我也假设N&lt;&lt;套数。
import java.util.*;
class Main {
public static void main(String[] args) {
// Just adding data here
Set<String> set1 = new HashSet<>();
set1.add("a"); set1.add("b"); set1.add("c");
Set<String> set2 = new HashSet<>();
set2.add("a"); set2.add("z"); set2.add("j");
Set<String> set3 = new HashSet<>();
set3.add("n"); set3.add("d"); set3.add("f");
//initial structure key= set name, value = actual set
Map<String, Set<String>> namedSets = new LinkedHashMap<String, Set<String>>();
namedSets.put("set1", set1);
namedSets.put("set2", set2);
namedSets.put("set3", set3);
// Real code
Map<String, ArrayList<Set<String>>> hashInter = new HashMap<>();
Set<Map.Entry<Set<String>, Set<String>>> result = new HashSet<>();
for (Map.Entry<String, Set<String>> entry : namedSets.entrySet()) {
for (String s : entry.getValue()) {
if (!hashInter.containsKey(s)) {
hashInter.put(s, new ArrayList<Set<String>>());
}
hashInter.get(s).add(entry.getValue());
}
}
for (Map.Entry<String, ArrayList<Set<String>>> entry : hashInter.entrySet()) {
ArrayList<Set<String>> vals = entry.getValue();
for (int i = 0; i < vals.size(); i++) {
for (int j = 0; j < vals.size(); j++) {
if (i >= j) {
continue;
}
Map.Entry<Set<String>, Set<String>> entryInter = new AbstractMap.SimpleEntry<Set<String>, Set<String>>(vals.get(i), vals.get(j));
result.add(entryInter);
}
}
}
result.stream().forEach(e -> System.out.println(e.getValue() + " " + e.getKey()));
}
}
产量
[a, z, j] [a, b, c]