Powerset (#8475)
* PowerSet generation is Java and respective unit tests are added * function name is adjusted to the actual ordering name (Reverse Lexicographical ordering) * Guava example test function is changed * LazyLoad powerSet (based on Guava implementation) is added * set is used instead of map.keySet() * Lexicographic Order and Gray Order are removed from function names. Unused function (rank and unrank), which are not used in the text, are removed
This commit is contained in:
parent
0577e41882
commit
ec9028d5f8
|
@ -1,7 +1,5 @@
|
|||
package com.baeldung.powerset;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.ArrayList;
|
||||
|
@ -163,7 +161,7 @@ public class PowerSetUtility<T> {
|
|||
return unMapIndex(powerSetIndices);
|
||||
}
|
||||
|
||||
private List<List<Boolean>> iterativePowerSetByLoopOverNumbersWithReverseLexicographicalOrder(int n) {
|
||||
private List<List<Boolean>> iterativePowerSetByLoopOverNumbers(int n) {
|
||||
List<List<Boolean>> powerSet = new ArrayList<>();
|
||||
for (int i = 0; i < (1 << n); i++) {
|
||||
List<Boolean> subset = new ArrayList<>(n);
|
||||
|
@ -174,7 +172,7 @@ public class PowerSetUtility<T> {
|
|||
return powerSet;
|
||||
}
|
||||
|
||||
private List<List<Boolean>> iterativePowerSetByLoopOverNumbersWithGrayCodeOrder(int n) {
|
||||
private List<List<Boolean>> iterativePowerSetByLoopOverNumbersWithMinimalChange(int n) {
|
||||
List<List<Boolean>> powerSet = new ArrayList<>();
|
||||
for (int i = 0; i < (1 << n); i++) {
|
||||
List<Boolean> subset = new ArrayList<>(n);
|
||||
|
@ -195,32 +193,16 @@ public class PowerSetUtility<T> {
|
|||
|
||||
public List<List<T>> iterativePowerSetByLoopOverNumbers(Set<T> set) {
|
||||
initializeMap(set);
|
||||
List<List<Boolean>> sets = iterativePowerSetByLoopOverNumbersWithReverseLexicographicalOrder(set.size());
|
||||
List<List<Boolean>> sets = iterativePowerSetByLoopOverNumbers(set.size());
|
||||
return unMapListBinary(sets);
|
||||
}
|
||||
|
||||
public List<List<T>> iterativePowerSetByLoopOverNumbersMinimalChange(Set<T> set) {
|
||||
initializeMap(set);
|
||||
List<List<Boolean>> sets = iterativePowerSetByLoopOverNumbersWithGrayCodeOrder(set.size());
|
||||
List<List<Boolean>> sets = iterativePowerSetByLoopOverNumbersWithMinimalChange(set.size());
|
||||
return unMapListBinary(sets);
|
||||
}
|
||||
|
||||
public static int getRankInLexicographicalOrder(List<Boolean> subset) {
|
||||
int rank = 0;
|
||||
for (int i = 0; i < subset.size(); i++)
|
||||
if (subset.get(i))
|
||||
rank += (1 << (subset.size() - i - 1));
|
||||
return rank;
|
||||
}
|
||||
|
||||
public static List<Boolean> getSubsetForRankInLexicographicalOrder(int rank, int sizeOfSet) {
|
||||
Boolean[] subset = new Boolean[sizeOfSet];
|
||||
for(int j = 0; j < sizeOfSet; j++) {
|
||||
subset[sizeOfSet - j - 1] = ((rank & (1 << j)) > 0);
|
||||
}
|
||||
return Arrays.asList(subset);
|
||||
}
|
||||
|
||||
private Set<Set<Integer>> recursivePowerSetIndexRepresentation(int idx, int n) {
|
||||
if (idx == n) {
|
||||
Set<Set<Integer>> empty = new HashSet<>();
|
||||
|
|
|
@ -137,7 +137,7 @@ public class PowerSetUtilityUnitTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_WhenPowerSetIsCalculatedIterativePowerSetByLoopOverNumbersMinimalChange_ThenItContainsAllSubsetsInGrayOrder() {
|
||||
public void givenSet_WhenPowerSetIsCalculatedIterativePowerSetByLoopOverNumbersWithMinimalChange_ThenItContainsAllSubsets() {
|
||||
|
||||
Set<String> set = RandomSetOfStringGenerator.generateRandomSet();
|
||||
List<List<String>> powerSet = new PowerSetUtility<String>().iterativePowerSetByLoopOverNumbersMinimalChange(set);
|
||||
|
@ -172,42 +172,6 @@ public class PowerSetUtilityUnitTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSubset_WhenPowerSetIsInLexicographicalOrder_ReturnCorrectRank() {
|
||||
int n = new Random().nextInt(5) + 5; //a number in [5, 10)
|
||||
for(int i = 0; i < ( 1 << n); i++) {
|
||||
Boolean[] subset = new Boolean[n];
|
||||
for(int j=0; j < n; j++) {
|
||||
subset[n - j - 1] = ((i & (1 << j)) > 0);
|
||||
}
|
||||
Assertions.assertEquals(i, PowerSetUtility.getRankInLexicographicalOrder(Arrays.asList(subset)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRanking_WhenPowerSetIsInLexicographicalOrder_ReturnTheSubset() {
|
||||
int n = new Random().nextInt(5) + 5; //a number in [5, 10)
|
||||
List<List<Boolean>> powerSet = new ArrayList<>();
|
||||
for(int i = 0; i < (1 << n); i++) {
|
||||
powerSet.add(PowerSetUtility.getSubsetForRankInLexicographicalOrder(i, n));
|
||||
}
|
||||
//To make sure that the size of power set is (2 power n)
|
||||
MatcherAssert.assertThat(powerSet, IsCollectionWithSize.hasSize((1 << n)));
|
||||
//To make sure that number of occurrence of each index is (2 power n-1)
|
||||
Map<Integer, Integer> counter = new HashMap<>();
|
||||
for (List<Boolean> subset : powerSet) {
|
||||
for (int i = 0; i < subset.size(); i++) {
|
||||
if(subset.get(i)) {
|
||||
int num = counter.getOrDefault(i, 0);
|
||||
counter.put(i, num + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
counter.forEach((k, v) -> Assertions.assertEquals((1 << (n - 1)), v.intValue()));
|
||||
//To make sure that one subset is not generated twice
|
||||
Assertions.assertEquals(powerSet.size(), new HashSet<>(powerSet).size());
|
||||
}
|
||||
|
||||
static class RandomSetOfStringGenerator {
|
||||
private static List<String> fruits = Arrays.asList("Apples", "Avocados", "Banana", "Blueberry", "Cherry", "Clementine", "Cucumber", "Date", "Fig",
|
||||
"Grapefruit"/*, "Grape", "Kiwi", "Lemon", "Mango", "Mulberry", "Melon", "Nectarine", "Olive", "Orange"*/);
|
||||
|
|
Loading…
Reference in New Issue