【问题标题】:How to get cartesian product from Map of String Set如何从字符串集的地图中获取笛卡尔积
【发布时间】:2014-06-18 14:09:28
【问题描述】:

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

我创建了以下

TreeMap<String, Set<String>> aMapOfSet

aMapOfSet 表示句子中的不同单词,Set&lt;String&gt; 将包含单词的所有变体,如果没有变体,则该单词键的 set 将为空/null。

我想写一个方法,它接受 aMapOfSet 并返回一个包含所有可能句子的集合。

例如,原句可以是:

tss xes wxy xyz

假设单词“wxy”总共有 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 a sentence with 1 space between words and add to resultSet
       }
    }

    return resultSet;

}

随着我的进步,我会更新代码。

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

【问题讨论】:

标签: java string dictionary treemap


【解决方案1】:

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

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. 您写了“我使用 treeMap 来保留单词的序列。”,但不幸的是,treemap 按其自然顺序(在本例中按字母表)对其键进行排序,不是按它们添加的时间.这就是为什么我将List&lt;String&gt; originalWords 作为参数包含在内,它确实保留了顺序。因此,您还需要对其进行初始化(将 ArrayListput(...) 紧跟在 aMapOfSet 中,也将 add(...) 放入列表中)。
  2. 此代码缺少几项检查,例如对 originalWordswordVariationSet 的空检查,检查 wordVariationSet 是否包含与 originalWords 相同的词,...
  3. 如果您的originalWords-sentence 包含两次相同的单词,wordVariationSet 将无法处理每个单词的不同变体。相反,您的第二个 put(...) 将覆盖您的第一个。

【讨论】:

  • +1,这就是我要找的。将对其进行测试。
  • 刚刚更新了一些注意事项。尤其是第 3 点可能是相关的!
  • 您知道,使用ArrayList&lt;Set&lt;String&gt;&gt; 可能更容易为您的wordVariationSet 添加项目,并按照添加单词到originalWords 的相同顺序添加项目,只需确保根据需要向其中添加空(或 null-)条目。这样,您也可以避免上面的问题 3(当然,除非您希望一个单词只有一组变体,即使该单词出现多次,在这种情况下,问题 3 将是一个功能,而不是错误)。
  • 谢谢!没错,实际上我在这里发布后最终使用了ArrayList&lt;Set&lt;String&gt;&gt; 。因为,正如您所指出的,TreeMap 没有给出正确的答案。
猜你喜欢
  • 1970-01-01
  • 2018-04-04
  • 2015-08-08
  • 2015-01-15
  • 1970-01-01
  • 2015-01-28
  • 1970-01-01
  • 2020-07-05
  • 2021-05-06
相关资源
最近更新 更多