Mathematics/algorithms was never my strong point (!) so requesting help on this one.
What is the most efficient implementation for a method with the following signature:
/*
* pairParts.size() > 0
* pairParts.size() is always an even number
*/
private Set<StringPairGroup> getAllPossibleStringPairGroups(Set<String> pairParts) {
Set<StringPairGroup> groups = new HashSet<StringPairGroup>();
// logic that adds all possible StringPairGroups
` return groups;
}
/*
* StringPair object: first and second values cannot be null.
* StringPair object: first != second
* StringPair object: is equal to another if both the first values and both the second values are equal.
*/
public class StringPair {
private final String first;
private final String second;
...
}
/*
* StringPairGroup object: is equal to another if their StringPair sets exactly match.
*/
public class StringPairGroup {
Set<StringPair> stringPairs
...
}
As an example an input of {‘A’, ‘B’} would return {[AB],[BA]}.
An input of {‘A’, ‘B’, ‘C’, ‘D’} would return
{[AB],[BA],[AC],[CA],[AD],[DA][…], [AB,CD],[BA,CD],[AB,DC],[BA,DC],[AC,DB],[…]}.
I am really just interested in the logic that creates all the possible StringPairGroups
for any set of input Strings. I could probably come up with some sort of brute force implementation but would rather know how to do something a lot ‘cleverer’.
So any hints as to how I would implement that would be useful.
Edit:
Sorry guys I think I may have missed off something quite important. I am really beggining to confuse myself. This is it:
A StringPairGroup cannot contain a repeated ‘pair part’ across all of its StringPairs. Does that make sense?
I understand the question as follows. There is a collection of N different strings (N is even),
e.g. A, B, C, D.
A pair is any concatenation of two different strings from this collection.
So, AB, BA are pairs, but AA is not a pair. A pair is different from another pair
if the corresponding concatenated strings are different strings. So, AB is different from BA,
and AB equals AB (obiously). There are N*N – N different pairs that can be built from
N different strings.
A group of order k is a set of k different pairs. So, [AB], [CD] are groups of order 1
because they both contain 1 pair.
[AB, CD], [BA, CD] are groups of order 2, because they both contain 2 pairs.
Two groups are equal if and only if they are equal as two sets. So, two equal
groups have exactly the same pairs; the order of the pairs does not matter. E.g.,
[AB, CD] and [BA, CD] are different groups because not all pairs in them are equal.
[AB, CD] and [CD, AB] are two equal groups.
All groups of order k can be constructed recursively:
3.1 Remove this pair from the collection C(N) of N strings, leaving a collection C(N-2)
of the remaining strings.
3.2 Construct all groups of order k-1 from C(N-2) and combine them with the pair P.
Here is a Java program (the complete code is on github:gist). An executable program in on ideone.
There are N/2 possible orders. Contruct the groups for all these orders and append them.
The recursive solution is well understandable but less efficient. If your N is large
then you would need a faster iterative solution. The iterative solution is less
illustrative than the recursive one and would not be suitable for the presentation here.
You can consult e.g. Knuth: The Art of Computer Programming, Vol. 4A: Combinatorial Algorithms.