我必须编写一种算法,可以从三个给定的集合中找到两个集合的交集。例如,如果该元素存在于三个集合中的两个集合中,则表示很好,但是如果该元素存在于所有三个集合中,则不应添加该元素
答案 0 :(得分:0)
答案 1 :(得分:0)
一个好的解决方案是将所有集合集合在一起,计算每个元素的频率,并只保留出现两次的元素
使用流
static <T> Set<T> intersectionTwoButNotThree(Set<T> s1, Set<T> s2, Set<T> s3) {
return Stream.of(s1, s2, s3)
.flatMap(Set::stream)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.filter(entry -> entry.getValue() == 2)
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
有循环
static <T> Set<T> intersectionTwoButNotThree(Set<T> s1, Set<T> s2, Set<T> s3) {
Map<T, Integer> map = new HashMap<>();
for (T elt : s1)
map.merge(elt, 1, Integer::sum); // sum previous value and 1
for (T elt : s2)
map.merge(elt, 1, Integer::sum); // sum previous value and 1
for (T elt : s3)
map.merge(elt, 1, Integer::sum); // sum previous value and 1
Set<T> set = new HashSet<>();
for (Map.Entry<T, Integer> e : map.entrySet())
if (e.getValue() == 2)
set.add(e.getKey());
return set;
}
答案 2 :(得分:0)
下面是我的尝试
public class Test {
List<Set> sets = new ArrayList<>();
Set<String> one = new HashSet<>();
Set<String> two = new HashSet<>();
Set<String> thr = new HashSet<>();
enum EStatus{
IT_IS_GOOD,
SHOULD_NOT_BE_ADDED,
EPIC_FAIL
}
public static void main(String[] args) {
Test mainT = new Test();
mainT.prepareData();
System.out.println(mainT.doStuff("three"));
}
public EStatus doStuff(String element){
for(int i = 1; i <= 3; i++){
Set<String> intersectionOfTwo = new HashSet<>(sets.get(i-1));
intersectionOfTwo.retainAll(sets.get(i % 3));
if(intersectionOfTwo.contains(element)){
Set<String> intersectionOfThree = new HashSet<>(intersectionOfTwo);
intersectionOfThree.retainAll(sets.get((i + 1) % sets.size()));
if(intersectionOfThree.contains(element)){
return EStatus.SHOULD_NOT_BE_ADDED;
}else{
return EStatus.IT_IS_GOOD;
}
}
}
return EStatus.EPIC_FAIL;
}
public void prepareData(){
one.add("one");
one.add("two");
one.add("three");
two.add("two");
two.add("three");
thr.add("three");
thr.add("four");
sets.add(one);
sets.add(two);
sets.add(thr);
}
}