Let's say I have the following:
john: [a, b, c, d]
bob: [a, c, d, e]
mary: [a, b, e, f]
Or reformatted slightly so you can easily see the groupings:
john: [a, b, c, d]
bob: [a, c, d, e]
mary: [a, b, e, f]
What's the most common or most efficient algorithm to generate the following grouping?
[john, bob, mary]: [a]
[john, mary]: [b]
[john, bob]: [c,d]
[bob, mary]: [e]
[mary]: [f]
[john]: []
[bob]: []
After quickly googling, it seems like the above keys represent the "power set". So I was planning on the following impl:
1) Generate power set {{j, b, m}, {j, m}, {j, b} {b, m}, {m}, {j}, {b}} // j = john, b = bob, m = mary
2) Generate set of all letters: {a, b, c, d, e, f}
3) Iterate over subsets, and for each letter, see if letter exists in all elements of the subset
So...
subset = {j, b, m}
letter = a
j contains a? true
b contains a? true
m contains a? true
* add a to subset {j, b, m}
letter = b
j contains b? true
b contains b? false, continue
letter = c
j contains c? true
b contains c? true
m contains c? false, continue
.....
subset = {j, m}
.....
Is there a better solution?
EDIT: The above algorithm is flawed. For instance, {j, m} would also contain "a", which I don't want. I suppose I can simply modify it so that in each iteration, I also check to see if this letter is "NOT IN" the elements not in this set. So in this case, I would also check:
if b does not contain a
Step 3 (Iterate over subsets) would be inefficient, as it does either "j contain a" or "a not in j" for each element in your power set.
Here is what I would suggest:
1) Generate power set {{j, b, m}, {j, m}, {j, b} {b, m}, {m}, {j}, {b}}. You don't need this step is you don't care about empty mappings in the final output.
2) Iterate over all the elements in your original data structure and construct following:
3) Reverse the above structure and aggregate (using maps of [j, b,...] to list of [a,b...] should do the trick) to get this:
4) Compare 3 with 1 to fill in the remaining empty mappings.
Edit: Hers is the complete code in Java
The output of the code above would be :