如果一个单词由两个有效单词组成

时间:2011-02-04 20:49:34

标签: algorithm language-agnostic

给定一个字典,找出给定的单词是否可以由字典中的两个单词组成。例如。如果有“报纸”,你必须找到它是否可以用两个词来表达。 (本案中的新闻和文件)。我能想到的只是从头开始并检查当前字符串是否是一个单词。在这种情况下,检查n,ne,new,news .....如果当前字符串是有效字,则检查剩余部分。

另外,你如何概括它为k(意味着一个单词是由k个单词组成的)?有什么想法吗?

3 个答案:

答案 0 :(得分:1)

在中心开始分割可能会更快地产生结果。例如,对于报纸,你首先会尝试拆分“新闻报纸”或“新闻报道”。如您所见,对于此示例,您将在第一次或第二次尝试时找到结果。如果您没有找到结果,只需向外搜索。请参阅下面的“弩”示例:

cros sbow
cro ssbow
cross bow

答案 1 :(得分:1)

对于有两个单词的情况,可以通过考虑将单词分成两部分的所有可能方法来解决问题,然后检查每一半以查看它是否是有效单词。如果输入字符串的长度为n,那么只有O(n)种不同的方法来分割字符串。如果将字符串存储在支持快速查找的结构中(例如,trie或哈希表)。

更有趣的情况是你有k>将单词分成2个单词。为此,我们可以使用非常优雅的递归表达式:

  

如果一个单词可以分成一个单词,后面跟一个可分为k - 1个单词的单词,则可以将它分成k个单词。

递归基本情况是,只有当一个单词是空字符串时,它才能被分成零​​个单词,这很简单。

为了使用这种递归的洞察力,我们将通过将所有可能的单词分割成两部分来修改原始算法。一旦我们进行了分割,我们就可以检查分割的第一部分是否为单词,以及分割的第二部分是否可以分解为k-1个单词。作为优化,我们不会对所有可能的分裂进行递归,而是仅针对我们知道第一个单词有效的那些。这是一些用Java编写的示例代码:

 public static boolean isSplittable(String word, int k, Set<String> dictionary) {
     /* Base case: If the string is empty, we can only split into k words and vice-
      * versa.
      */
     if (word.isEmpty() || k == 0)
         return word.isEmpty() && k == 0;

     /* Generate all possible non-empty splits of the word into two parts, recursing on
      * problems where the first word is known to be valid.
      *
      * This loop is structured so that we always try pulling off at least one letter
      * from the input string so that we don't try splitting the word into k pieces
      * of which some are empty.
      */
     for (int i = 1; i <= word.length(); ++i) {
          String first = word.substring(0, i), last = word.substring(i);

          if (dictionary.contains(first) &&
              isSplittable(last, k - 1, dictionary)
              return true;
     }

     /* If we're here, then no possible split works in this case and we should signal
      * that no solution exists.
      */
     return false;
 }

 }

在最坏的情况下,此代码在时间O(n k )中运行,因为它尝试将字符串的所有可能分区生成为k个不同的部分。当然,它不太可能达到这种最坏情况的行为,因为大多数可能的分裂不会最终形成任何单词。

答案 2 :(得分:0)

我首先使用strpos(-like)函数循环遍历字典,以检查它是否完全出现。然后尝试是否可以找到与结果匹配的内容。 所以它会做这样的事情:

  • 循环翻译字典中的每个单词并将结果保存到数组中,假设它给我的结果是“新”,“纸张”和“新闻”。
  • 检查是否有新的+纸张==报纸,检查新的+新闻==报纸等,直到你得到纸张+新闻==报纸返回。

不确定它是否是一个好的方法,但它似乎比检查字母的字母(更多的迭代)更有效,而你没有解释你如何检查第二个单词何时开始。

不知道你的意思是'你怎么把它概括为k'。