Google
 
Web unafbapune.blogspot.com

Tuesday, September 02, 2008

 

Visiting Every Combination ?

Given a set of objects, sometimes it's useful to find out all the combination of these objects of a given size, and perform some action upon each combination. For example, given a set of letters "abcde", print out all the combination of 4 letters from the set.

How would you go about writing such utility efficiently in Java ?

One possible answer:
public class Combination<T> {
public static interface Visitor<T> {
/** Visits each k-combination of objects. */
public void visit(T[] entry);
}
private final T[] objects; // Given set of objects
private final T[] entry; // each combination of size k
private final Visitor<T> visitor;

/**
* @param objects set of n objects
* @param k size of each combination
* @param visitor used to visit each combination
*/
public Combination(T[] objects, int k, Visitor<T> visitor) {
this.objects = objects.clone();
entry = Arrays.copyOf(this.objects, k);
this.visitor = visitor;
}

public void compute() { doCompute(0, 0); }

private void doCompute(int pos, int entryPos) {
if (entryPos == entry.length) {
visitor.visit(entry);
return;
}
// (entry.length - entryPos) is the remaining size
for (int i = pos, end = objects.length - (entry.length - entryPos) + 1; i < end; i++) {
entry[entryPos] = objects[i];
doCompute(i + 1, entryPos + 1);
}
}
}
Demo:
Visitor<Character> visitor = new Visitor<Character>() {
private Set<String> set = new HashSet<String>();

@Override
public void visit(Character[] entry) {
String s = Arrays.toString(entry);
set.add(s);
System.out.println(set.size() + ": " + s);
}
};
String s = "abcde";
Character[] ca = new Character[s.length()];

for (int i = s.length() - 1; i > -1; i--)
ca[i] = s.charAt(i);

final int size = 4;
new Combination<Character>(ca, size, visitor).compute();
Would yield:
1: [a, b, c, d]
2: [a, b, c, e]
3: [a, b, d, e]
4: [a, c, d, e]
5: [b, c, d, e]

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?