I have an string array
{"ted", "williams", "golden", "voice", "radio"}
and I want all possible combinations of these keywords in the following form:
{"ted",
"williams",
"golden",
"voice",
"radio",
"ted williams",
"ted golden",
"ted voice",
"ted radio",
"williams golden",
"williams voice",
"williams radio",
"golden voice",
"golden radio",
"voice radio",
"ted williams golden",
"ted williams voice",
"ted williams radio",
.... }
I've been going for hours with no effective result (side effect of high-level programming ??).
I know the solution should be obvious but I'm stuck, honestly ! Solutions in Java/C# are accepted.
EDIT:
EDIT 2: after reviewing the link in the answer, it turns out that Guava users can have the powerset method in com.google.common.collect.Sets
Use Recurrence to Generate All Possible Combinations in Java First, we create an empty array that will store the outputs. The idea is to fix elements one by one and then use recurrence. Finally, when the number of elements in the initial array becomes equal to the size of combinations, then we print the initial array.
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. To calculate a combination, you will need to calculate a factorial.
Method 1 (Fix Elements and Recur) We first fix 1 at index 0 in data[], then recur for remaining indexes, then we fix 2 at index 0 and recur. Finally, we fix 3 and recur for remaining indexes. When number of elements in data[] becomes equal to r (size of a combination), we print data[].
Given an array of size n, generate and print all possible combinations of r elements in array. For example, if input array is {1, 2, 3, 4} and r is 2, then output should be {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4} and {3, 4}. Following are two methods to do this. We create a temporary array ‘data []’ which stores all outputs one by one.
For a combination of r elements from an array of size n, a given element may be included or excluded from the combination. Let’s have a Boolean array of size n to label whether the corresponding element in data array is included.
Following are two methods to do this. We create a temporary array ‘data []’ which stores all outputs one by one. The idea is to start from first index (index = 0) in data [], one by one fix elements at this index and recur for remaining indexes. Let the input array be {1, 2, 3, 4, 5} and r be 3.
Let the input array be {1, 2, 3, 4, 5} and r be 3. We first fix 1 at index 0 in data [], then recur for remaining indexes, then we fix 2 at index 0 and recur. Finally, we fix 3 and recur for remaining indexes.
EDIT: As FearUs pointed out, a better solution is to use Guava's Sets.powerset(Set set).
EDIT 2: Updated links.
Quick and dirty translation of this solution:
public static void main(String[] args) {
List<List<String>> powerSet = new LinkedList<List<String>>();
for (int i = 1; i <= args.length; i++)
powerSet.addAll(combination(Arrays.asList(args), i));
System.out.println(powerSet);
}
public static <T> List<List<T>> combination(List<T> values, int size) {
if (0 == size) {
return Collections.singletonList(Collections.<T> emptyList());
}
if (values.isEmpty()) {
return Collections.emptyList();
}
List<List<T>> combination = new LinkedList<List<T>>();
T actual = values.iterator().next();
List<T> subSet = new LinkedList<T>(values);
subSet.remove(actual);
List<List<T>> subSetCombination = combination(subSet, size - 1);
for (List<T> set : subSetCombination) {
List<T> newSet = new LinkedList<T>(set);
newSet.add(0, actual);
combination.add(newSet);
}
combination.addAll(combination(subSet, size));
return combination;
}
Test:
$ java PowerSet ted williams golden
[[ted], [williams], [golden], [ted, williams], [ted, golden], [williams, golden], [ted, williams, golden]]
$
I just faced this problem and wasn't really happy with the StackExchange answers posted, so here's my answer. This returns all combinations from an array of Port
objects. I'll leave it to the reader to adapt to whatever class you're using (or make it generic).
This version does not use recursion.
public static Port[][] combinations ( Port[] ports ) {
List<Port[]> combinationList = new ArrayList<Port[]>();
// Start i at 1, so that we do not include the empty set in the results
for ( long i = 1; i < Math.pow(2, ports.length); i++ ) {
List<Port> portList = new ArrayList<Port>();
for ( int j = 0; j < ports.length; j++ ) {
if ( (i & (long) Math.pow(2, j)) > 0 ) {
// Include j in set
portList.add(ports[j]);
}
}
combinationList.add(portList.toArray(new Port[0]));
}
return combinationList.toArray(new Port[0][0]);
}
See solution by @Aison on this page for a more optimized version.
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