I have n
Sets. Each Set has different number of elements. I would like to write an algorithm which give me all possible combinations from the sets. For example, let's say we have:
S1={1,2}, S2={A,B,C}, S3={$,%,£,!}
a combination should look like
C1={1,A,$}
C2={1,A,%}
...
...and so on. The number of possible combination will be 2*3*4 = 24
Please Help me to write this algorithm in Java.
The formula for combinations is generally n! / (r! (n -- r)!), where n is the total number of possibilities to start and r is the number of selections made. In our example, we have 52 cards; therefore, n = 52. We want to select 13 cards, so r = 13.
Combinations are a way to calculate the total outcomes of an event where order of the outcomes does not matter. To calculate combinations, we will use the formula nCr = n! / r! * (n - r)!, where n represents the total number of items, and r represents the number of items being chosen at a time.
There are 10,000 possible combinations that the digits 0-9 can be arranged into to form a four-digit code.
Answer and Explanation: The number of possible combinations with 4 numbers without repetition is 15. The formula we use to calculate the number of n element combinations when repetition is not allowed is 2n - 1.
Recursion is your friend:
public class PrintSetComb {
public static void main(String[] args) {
String[] set1 = {"1", "2"};
String[] set2 = {"A", "B", "C"};
String[] set3 = {"$", "%", "£", "!"};
String[][] sets = {set1, set2, set3};
printCombinations(sets, 0, "");
}
private static void printCombinations(String[][] sets, int n, String prefix) {
if (n >= sets.length) {
System.out.println("{" + prefix.substring(0, prefix.length() - 1) + "}");
return;
}
for (String s : sets[n]) {
printCombinations(sets, n + 1, prefix + s + ",");
}
}
}
In response to question from OP about generalizing it to sets of Objects:
public class PrintSetComb {
public static void main(String[] args) {
Integer[] set1 = {1, 2};
Float[] set2 = {2.0F, 1.3F, 2.8F};
String[] set3 = {"$", "%", "£", "!"};
Object[][] sets = {set1, set2, set3};
printCombinations(sets, 0, new Object[0]);
}
private static void printCombinations(Object[][] sets, int n, Object[] prefix) {
if (n >= sets.length) {
String outp = "{";
for (Object o : prefix) {
outp = outp + o.toString() + ",";
}
System.out.println(outp.substring(0, outp.length() - 1) + "}");
return;
}
for (Object o : sets[n]) {
Object[] newPrefix = Arrays.copyOfRange(prefix, 0, prefix.length + 1);
newPrefix[newPrefix.length - 1] = o;
printCombinations(sets, n + 1, newPrefix);
}
}
}
And finally an iterative variant. It is based on increasing an array of counters where the counter wraps and carries when it reaches the size of the set:
public class PrintSetCombIterative {
public static void main(String[] args) {
String[] set1 = {"1", "2"};
String[] set2 = {"A", "B", "C"};
String[] set3 = {"$", "%", "£", "!"};
Object[][] sets = {set1, set2, set3};
printCombinations(sets);
}
private static void printCombinations(Object[][] sets) {
int[] counters = new int[sets.length];
do {
System.out.println(getCombinationString(counters, sets));
} while (increment(counters, sets));
}
private static boolean increment(int[] counters, Object[][] sets) {
for (int i = counters.length - 1; i >= 0; i--) {
if (counters[i] < sets[i].length - 1) {
counters[i]++;
return true;
} else {
counters[i] = 0;
}
}
return false;
}
private static String getCombinationString(int[] counters, Object[][] sets) {
String combo = "{";
for (int i = 0; i < counters.length; i++) {
combo = combo + sets[i][counters[i]] + ",";
}
return combo.substring(0, combo.length() - 1) + "}";
}
}
In the case someone wants the matrix instead of printing, I slightly modified the code:
public class TestSetCombinations2 {
public static void main(String[] args) {
Double[] set1 = {2.0, 3.0};
Double[] set2 = {4.0, 2.0, 1.0};
Double[] set3 = {3.0, 2.0, 1.0, 5.0};
Double[] set4 = {1.0, 1.0};
Object[][] sets = {set1, set2, set3, set4};
Object[][] combinations = getCombinations(sets);
for (int i = 0; i < combinations.length; i++) {
for (int j = 0; j < combinations[0].length; j++) {
System.out.print(combinations[i][j] + " ");
}
System.out.println();
}
}
private static Object[][] getCombinations(Object[][] sets) {
int[] counters = new int[sets.length];
int count = 1;
int count2 = 0;
for (int i = 0; i < sets.length; i++) {
count *= sets[i].length;
}
Object[][] combinations = new Object[count][sets.length];
do {
combinations[count2++] = getCombinationString(counters, sets);
} while (increment(counters, sets));
return combinations;
}
private static Object[] getCombinationString(int[] counters, Object[][] sets) {
Object[] o = new Object[counters.length];
for (int i = 0; i < counters.length; i++) {
o[i] = sets[i][counters[i]];
}
return o;
}
private static boolean increment(int[] counters, Object[][] sets) {
for (int i = counters.length - 1; i >= 0; i--) {
if (counters[i] < sets[i].length - 1) {
counters[i]++;
return true;
} else {
counters[i] = 0;
}
}
return false;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With