This is something I tried based on the requirement:
- if two sets are same, keep only one set
- remove sub sets of any set
- also, there is a flexibility how the input data is
The input data format is modified to use List<int[]>
instead of List<Set<Integer>>
. The reasons are that the integer sets are not changed during the process and an int[]
may perform better and I found it simple to use. I created a wrapper around the input integer sets data as IntegerSet
and worked with it.
Here is the code:
import java.util.*;
import java.util.stream.*;
public class IntegerSetProcess {
public static void main(String[] args) {
// Input data
List<IntegerSet> inputList =
Arrays.asList(new IntegerSet(new int [] {11}),
new IntegerSet(new int [] {12, 555}),
new IntegerSet(new int [] {2, 333, 555, 9, 144, 89}),
new IntegerSet(new int [] {12}),
new IntegerSet(new int [] {12, 3, 555, 90, 42, 789, 15000}),
new IntegerSet(new int [] {2, 555, 9, 89, 333, 144}),
new IntegerSet(new int [] {555, 12}),
new IntegerSet(new int [] {222, 12, 41320, 0, 769942}),
new IntegerSet(new int [] {910, 77}));
// Distinct IntegerSets
List<IntegerSet> distinctList =
inputList.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
// Filter subsets to get result
List<IntegerSet> resultList = doSubsetFiltering(distinctList);
// Result data in original form (optional)
resultList.stream()
.forEach(e -> System.out.println(Arrays.toString(e.getOriginal())));
}
/*
* Takes the input List<IntegerSet> and removes all the IntegerSets with
* elements as subset in any other IntegerSet.
*/
private static List<IntegerSet> doSubsetFiltering(List<IntegerSet> listIs) {
List<IntegerSet> removedIs = new ArrayList<>();
OUTER_LOOP: // size-1, the last element is not iterated
for (int i = 0; i < listIs.size()-1; i++) {
IntegerSet thisIs = listIs.get(i);
INNER_LOOP: // i+1, the checking starts from the next IntegerSet
for (int j = i+1; j < listIs.size(); j++) {
IntegerSet nextIs = listIs.get(j);
if (isSubset(thisIs.getData(), nextIs.getData())) {
// To remove thisIs set as it is a subset of isNext
removedIs.add(thisIs);
break INNER_LOOP;
}
} // inner-for-loop
} // outer for-loop
listIs.removeAll(removedIs);
return listIs;
}
// Returns true if the input array thisIs has all its elements in nextIs.
public static boolean isSubset(int[] thisIs, int[] nextIs) {
for(int i : thisIs) {
if (Arrays.binarySearch(nextIs, i) < 0) {
return false;
}
}
return true;
}
}
import java.util.*;
import java.util.stream.*;
public class IntegerSet implements Comparable<IntegerSet> {
private int[] data;
private int[] original;
public IntegerSet(int[] intput) {
original = IntStream.of(intput).toArray();
data = intput;
Arrays.sort(data);
}
public int[] getData() {
return data;
}
public int[] getOriginal() {
return original;
}
@Override
public String toString() {
return Arrays.toString(data);
}
@Override
public boolean equals(Object obj) {
IntegerSet is = (IntegerSet) obj;
if (Arrays.equals(data, is.getData())) {
return true;
}
return false;
}
@Override
public int hashCode() {
return data.length;
}
@Override
public int compareTo(IntegerSet is) {
return Integer.valueOf(data.length).compareTo(is.getData().length);
}
}