This might be similar to Java : Cartesian Product of a List of Lists but not answering my question.
I created the following
TreeMap<String, Set<String>> aMapOfSet
aMapOfSet
represents different words in a sentence and Set<String>
will contain all variations to the words if there is no variation then set will be empty/null for that word key.
I want to write a method that would take aMapOfSet and returns a Set of all possible sentences.
For instance, the original sentence could be:
tss xes wxy xyz
suppose there are total of 3 variations for the word "wxy" and total of 2 variations for the word "xyz"
Then aMapOfSet would look like this
tss
xes
wxy -> [wxys,wxyes]
xyz -> [xyzs]
The answer would be 6 sentences in resultSet
tss xes wxy xyz
tss xes wxys xyz
tss xes wxyes xyz
tss xes wxy xyzs
tss xes wxys xyzs
tss xes wxyes xyzs
I used treeMap to preserve the sequence of words.
Here is my work in progress code:
Set<String> getCartesianProduct(TreeMap<String, Set<String>> wordVariationSet)
{
Set<String> resultSet =new HashSet<String>();// to store answer
for(String theOriginalWord: wordVariationSet.keySet())
{
for(String word:wordVariationSet.get(theOriginalWord))
{
// TODO create a sentence with 1 space between words and add to resultSet
}
}
return resultSet;
}
I will update the code as I make more progress.
What is the best way to iterate through all variations, so to get all 6 sentences.
This might be a good time to use recursion:
Set<String> getCartesianProduct(List<String> originalWords, TreeMap<String, Set<String>> wordVariationSet) {
Set<String> resultSet =new HashSet<String>(); // to store answer
varyWord(resultSet, "", originalWords, wordVariationSet, 0); // begin recursion with empty sentence
return resultSet; // return result
}
void varyWord(Set<String> result, String sentence, List<String> originalWords, Map<String, Set<String>> wordVariationSet, int index) {
if (index==originalWords.size()) { // no more words to vary -> sentence is complete
result.add(sentence); // add to results
return; // done (return from recursion)
}
if (index>0) sentence += " "; // add a space if working on any but first word
String theOriginalWord = originalWords.get(index); // grab original word
varyWord(result, sentence + theOriginalWord, originalWords, wordVariationSet, index+1); // add to sentence and vary next word
Set<String> wordVariations = wordVariationSet.get(theOriginalWord); // grab variations of this word
if (wordVariations!=null) // make sure they're not null
for(String word: wordVariations) // iterate over variations
varyWord(result, sentence + word, originalWords, wordVariationSet, index+1); // add to sentence and vary next word
}
I hope this code is self-explanatory. If not, let me know and I can add some detail.
A couple of things to note:
List<String> originalWords
as a parameter, which does preserve ordering. So, you will need to initialize that as well (make an ArrayList
and right after you put(...)
a word into aMapOfSet
, also add(...)
it to the list).originalWords
and wordVariationSet
, a check whether wordVariationSet
contains the same words as originalWords
, ...originalWords
-sentence contains the same word twice, the wordVariationSet
will not be able to handle different variations for each. Instead, your second put(...)
will overwrite your first one.