Suppose I have an array.
String[] arr = {"a", "b", "c"};
I need to get all possible combinations, like this:
a
a b
a c
a b c
a c b
b
b a
b c
b a c
b c a
c
c a
c b
c a b
c b a
What fast algorithm should I use to get all combinations?
UPD
public static void permute(List<Integer> done, List<Integer> remaining {
remaining.removeAll(Collections.<Integer>singletonList(null));
done.removeAll(Collections.<Integer>singletonList(null));
System.out.println(done);
if (remaining.size() == 0) {
return;
}
for (int i = 0; i < remaining.size(); i++) {
Integer e = remaining.get(i);
done.add(e);
remaining.set(i, null);
permute(done, remaining);
remaining.add(e);
done.set(i, null);
}
}
Output
[]
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[2, 3, 4, 3]
[2, 3, 4, 3, 4]
[4, 3, 4, 3]
[4, 3, 4, 3, 4]
[4, 3, 4, 3, 4, 2]
[3, 4, 3, 4, 2, 4]
[3, 4, 3, 4, 2, 4, 2]
[3, 4, 2, 4, 2, 3]
[3, 4, 2, 4, 2, 3, 2]
[3, 4, 2, 4, 2, 3, 2, 4]
[4, 2, 4, 2, 3, 2, 4, 2]
[4, 2, 4, 2, 3, 2, 4, 2, 4]
[2, 3, 2, 4, 2, 4, 2]
[2, 3, 2, 4, 2, 4, 2, 4]
[2, 3, 2, 4, 2, 4, 2, 4, 3]
[2, 3, 2, 4, 2, 4, 2, 4, 3, 1]
[3, 2, 4, 2, 4, 2, 4, 3, 1, 3]
[3, 2, 4, 2, 4, 2, 4, 3, 1, 3, 1]
[4, 2, 4, 2, 4, 3, 1, 3, 1, 3]
[4, 2, 4, 2, 4, 3, 1, 3, 1, 3, 1]
[4, 2, 4, 2, 4, 3, 1, 3, 1, 3, 1, 4]
[2, 4, 2, 4, 3, 1, 3, 1, 3, 1, 4, 1]
[2, 4, 2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4]
[2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3]
[2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4]
[2, 4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 1]
[4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4]
[4, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1]
[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3]
[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1]
[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4]
[3, 1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2]
[1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4]
[1, 3, 1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2]
[1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4]
[1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2]
[1, 4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1]
[4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2]
[4, 1, 4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1]
[4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4]
[4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1]
[4, 3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2]
[3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1]
[3, 4, 1, 4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2]
[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3]
[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2]
[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1]
[4, 1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4]
[1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1]
[1, 3, 1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4]
[1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1]
[1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4]
[1, 4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2]
[4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4]
[4, 2, 4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2]
[4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1]
[4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2]
[4, 2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2, 4]
[2, 4, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2, 4, 2]
[2, 4
, 2, 1, 2, 1, 4, 1, 2, 1, 2, 3, 2, 1, 4, 1, 4, 1, 4, 2, 4, 2, 1, 2, 4, 2, 4]
UPD3
I found some code and made redesign of it. So I got this:
public class Permutations {
public static void main(String[] args) {
Set<String> combos = new Permutations().combos("1", "2", "3", "4", "5");
for (String combo : combos) {
for (char e : combo.toCharArray()){
System.out.printf("[%s]", e);
}
System.out.println();
}
}
public Set<String> combos(String... input) {
Set<String> set = new TreeSet<>();
combos(input, set, input.length, new StringBuffer());
return set;
}
private void combos(String[] input, Set<String> set, int len, StringBuffer buf) {
if (len == 0) {
String elem = unique(buf.toString());
set.add(elem);
} else {
for (String t : input) {
buf.append(t);
combos(input, set, len - 1, buf);
buf.deleteCharAt(buf.length() - 1);
}
}
}
private String unique(String input) {
StringBuilder unique = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
String si = input.substring(i, i + 1);
if (unique.indexOf(si) == -1)
unique.append(si);
}
return unique.toString();
}
}
It works fine.