如何从字符串集的Map中获取笛卡尔积

时间:2014-05-02 00:20:11

标签: java string map treemap

这可能类似于Java : Cartesian Product of a List of Lists,但没有回答我的问题。

我创建了以下

TreeMap<String, Set<String>> aMapOfSet

aMapOfSet表示句子中的不同字词,Set<String>将包含字词的所有变体,如果没有变化,则对于该字词键,设置将为空/ null。

我想写一个方法,它将采用一个MapOfSet并返回一组所有可能的句子。

例如,原始句子可以是:

tss xes wxy xyz

假设单词xxy有3个变体,单词xyz有2个变体

然后aMapOfSet看起来像这样

tss
xes
wxy -> [wxys,wxyes]
xyz -> [xyzs]

答案是resultSet

中的6个句子
tss xes wxy xyz
tss xes wxys xyz
tss xes wxyes xyz

tss xes wxy xyzs
tss xes wxys xyzs
tss xes wxyes xyzs

我使用treeMap来保存单词序列。

这是我正在进行的工作代码:

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 sentence with 1 space between words and add to resultSet
       }
    }

    return resultSet;

}

随着我取得更多进展,我会更新代码。

迭代所有变体的最佳方法是什么,以便获得所有6个句子。

1 个答案:

答案 0 :(得分:2)

这可能是使用递归的好时机:

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
}

我希望这段代码不言自明。如果没有,请告诉我,我可以添加一些细节。

有几点需要注意:

  1. 你写了#34;我使用了treeMap来保存单词的序列。&#34;,但不幸的是,树图按其自然顺序(在这种情况下通过字母表)对其键进行排序,当它们被添加时。这就是我将List<String> originalWords作为参数包含在内的原因,它确实保留了排序。因此,您还需要对其进行初始化(在ArrayList之后put(...)aMapOfSet之后立即生成add(...),并将其originalWords添加到列表中。
  2. 此代码缺少一些检查,例如wordVariationSetwordVariationSet的空检查,检查originalWords是否包含与originalWords相同的单词,。 ..
  3. 如果您的wordVariationSet - 句子包含两次相同的字词,则put(...)将无法处理每个字词的不同变体。相反,您的第二个{{1}}将覆盖您的第一个。{/ li>