0

I want to write a method that uses the standard for loop to iterate through a given set of sets, and returns a hashmap that the disjoint sets are added to. I'm aware that the does not work correctly, it's an example of how I've tried to solve this. How do I check the elements within the sets, also without the algorithm becoming too inefficient?

public <E> Map<Set<E>, Set<Set<E>>> disjointSets(Set<Set<E>> Sets) {
    Map<Set<E>, Set<Set<E>>> result = new HashMap<>();

    for (Set<E> x : Sets) {
        for (Set<E> y : Sets) {
            if (!x.equals(y)) {
                result.put(x, Sets);
            }
        }
    }
    return result;
}
/**
 * As an example, if input sets would be:
 * [0]
 * [0, 4, 5]
 * [1, 2]
 * -> expected output should be:
 * [0] : [ [1, 2] ]
 * [0, 4, 5] : [ [1, 2] ]
 * [1, 2] : [ [0] [0, 4, 5] ]
 */
4
  • feel free to say if something needs to be clarified Commented Oct 10, 2022 at 20:41
  • Please do clarify what you are trying to achieve, example input helps. The value of x will always equals a y (when x==y itself) so you get same outcome by removing the inner for and if statements, and get a map containing a key for every member of Sets, and every value is Sets. Commented Oct 10, 2022 at 21:04
  • @DuncG For example, if the input Sets are: ' [0] [0, 4, 5] [1, 2] ' The method output should be: ' [0] : [ [1, 2] ], [0, 4, 5] : [ [1, 2] ], [1, 2] : [ [0] [0, 4, 5] ] ' where the each key is a set checked, and the value for each key is the sets disjoint from the key set. I'm still trying to figure out HashMap, so I know my code is far from the correct way to achieve this. Commented Oct 10, 2022 at 21:23
  • @AlexanderIvanchenko I think there is a misunderstanding here. I know the definition of "disjoint". In the output example, I have used commas to separate each key & their value. I understand that was a poor way to display that. So in my example for set [1, 2] the disjoint sets are [0], [0, 4, 5]. The ":" separates a key from it's own value. I hope this clarifies everything. Commented Oct 10, 2022 at 22:24

2 Answers 2

0

How do I check the elements within the sets

You can just cycle trough them and use Set.contains

for (Set<E> x : Sets) {
    for (Set<E> y : Sets) {
        boolean isDisjoint = true;
        for (E ey : y) {
            if (x.contains(ey)) {
                isDisjoint = false;
                break;
            }
        }
        ...
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks! But what if I don't want to use the boolean? Can I just leave it out and make it work like that?
Update: that works! Now I have the compared sets added to the result Map as keys, but each keys value has to be a set of the other sets that are disjoint. I tried to put this condition: if (!x.contains(ey)) { result.put(x, y); } but it gives me an error for the y, because there has to be a Set<Set<E>> placed there. How do I add all of the disjoint sets to the keys value?
@bells check Map.computeIfAbsent
What do I do if the key set does not have any disjoint sets? I want the key value to be empty, like this '[ ]'
0

You can generate a map of type Map<E,Set<Set<E>>> which associates each distinct element which might be found in these Sets with a group of Sets to which it belongs. This approach would allow to avoid redundant performing redundant iterations.

A disjoint Set that corresponds to each Set can be found in the following steps:

  • For each Set create a copy of the given Sets (that would be a value that corresponds to a particular set in the resulting map);

  • Iterate over the elements of a current Set and remove a value (denoted as disjoint in the code below) of all Sets to which a particular element belongs. A previously generated Map containing Sets associated with each distinct element would be handy for that.

In the code below, I've used Java 8 method computeIfAbsent(), which is concise and expressive (an alternative option provided in the comments):

public static <E> Map<Set<E>, Set<Set<E>>> disjointSets(Set<Set<E>> sets) {

    Map<E, Set<Set<E>>> containsElement = new HashMap<>();
    
    for (Set<E> set: sets) {
        for (E next: set) {
            containsElement   // alternatively you can use: containsElement.putIfAbsent() + containsElement.get()add()
                .computeIfAbsent(next, k -> new HashSet<>())
                .add(set);
        }
    }
    
    Map<Set<E>, Set<Set<E>>> result = new HashMap<>();
    
    for (Set<E> set: sets) {
        Set<Set<E>> disjoint = new HashSet<>(sets);
        result.put(Collections.unmodifiableSet(set), disjoint);
        
        for (E next: set) {
            disjoint.removeAll(containsElement.get(next));
        }
    }
    return result;
}

main()

public static void main(String[] args) {
    Set<Set<Integer>> sets = Set.of(
        Set.of(0), Set.of(0, 4, 5), Set.of(1, 2)
    );
    
    disjointSets(sets).forEach((element, disjoint) -> System.out.println(element + " -> " + disjoint));
}

Output:

[0] -> [[1, 2]]
[1, 2] -> [[0], [0, 5, 4]]
[0, 5, 4] -> [[1, 2]]

Time Complexity: O(n*m) (considering that we are given n sets containing m elements).

4 Comments

Thank you for your effort. I would prefer not creating any copies of the given sets, they have to be referred to.
@bells What you're talking about is inherently impossible - every value should be represented with a separate Set of Sets (otherwise they would all be identical, which makes no sense). And I guess have a misconception regarding what copy-constructor of any Collection does. new Set<>(sets) creates a so-called shallow copy, i.e. none of the nested Sets would be actually copied, but instead references to them would be placed into a newly created Set of Set. Is it clear?
Yes. What is the time complexity for this algorithm?
@bells Time complexity of this solution O(n*m) (considering that we are given n sets containing m elements), which is the best possible in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.