I have the following function:
public ArrayList<ArrayList<Word>> createSentences(ArrayList<ArrayList<Word>> gestures, int startIndex) {
if (gestures.size() == 1) {
return gestures;
}
ArrayList<Word> ret;
ArrayList<ArrayList<Word>> result = new ArrayList<ArrayList<Word>>();
ArrayList<Word> tmp1 = gestures.get(0);
gestures.remove(0);
ArrayList<ArrayList<Word>> tmp2 = createS开发者_开发技巧entences(gestures, startIndex + 1);
for (Word s : tmp1) {
for (Word s2 : tmp2.get(0)) {
ret = new ArrayList<Word>();
ret.add(s);
ret.add(s2);
result.add(ret);
}
}
return result;
}
Given an input:
ArrayList<ArrayList<Word>> test= new ArrayList<ArrayList<Word>>();
ArrayList<Word> gest1 = new ArrayList<Word>();
gest1.add(new Word("A", "N"));
gest1.add(new Word("B", "V"));
ArrayList<Word> gest2 = new ArrayList<Word>();
gest2.add(new Word("C", "N"));
gest2.add(new Word("D", "V"));
test.add(gest1);
test.add(gest2);
It produces following results:
[A, C]
[A, D]
[B, C]
[B, D]
which is fine but given an input:
ArrayList<ArrayList<Word>> test= new ArrayList<ArrayList<Word>>();
ArrayList<Word> gest1 = new ArrayList<Word>();
gest1.add(new Word("A", "N"));
gest1.add(new Word("B", "V"));
ArrayList<Word> gest2 = new ArrayList<Word>();
gest2.add(new Word("C", "N"));
gest2.add(new Word("D", "V"));
ArrayList<Word> gest3 = new ArrayList<Word>();
gest3.add(new Word("E", "N"));
gest3.add(new Word("F", "V"));
test.add(gest1);
test.add(gest2);
test.add(gest3);
It produces:
[A, C]
[A, E]
[B, C]
[B, E]
where I would like to achieve all possible combinations of matching like this:
[A, C, E]
[A, C, F]
[A, D, E]
[A, D, F]
[B, C, E]
[B, C, F]
[B, D, E]
[B, D, F]
Can somebody help me and rewrite the function to produce wanted results.
Nest another loop in the two that already exist.
Or use a recursive algorithm which will work for any number of input word-lists.
[EDIT]
To make it more simple for you to understand what is going on, here are a couple of suggestions:
Create new types like
class WordList extends ArrayList<Word> {}
andclass Sentence extends ArrayList<Word> {}
That helps to make clear what you want. The code will be more readable.Add helper methods to the new types. For example, add
List<Sentence> appendWords( WordList )
toSentence
to create new sentences from the original one where each has one word of the word list appended. That allows you to keep the code simple: Each method does exactly one thing.
That allows you to make the final algorithm pretty simple:
List<Sentence> result = new ArrayList<Sentence>();
result.add( new Sentence() ); // start with an empty sentence
for( WordList words : wordLists ) {
List<Sentence> tmp = new ArrayList<Sentence>();
for( Sentence s : result ) {
tmp.addAll( s.appendWords( words ) );
}
result = tmp;
}
For each iteration of the main loop, all words of the next word list are appended to all previous results.
This line
for (Word s2 : tmp2.get(0)) {
means something like "for every word in the first sentence of tmp2". Why do you ignore the other sentencestmp2.get(1)
, tmp2.get(2)
, etc?
What you need is, "add every word from tmp1 to every sentence in tmp2", right?
for (Word word : tmp1) {
for (List<Word> sentence : tmp2) {
List<Word> tempSentence = new ArrayList<Word>();
tempSentence.add(word);
tempSentence.addAll(sentence);
result.add(tempSentence);
}
}
精彩评论