【问题标题】:If a word is made up of two valid words如果一个词由两个有效词组成
【发布时间】:2011-02-04 20:49:34
【问题描述】:

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

你如何将它概括为 k(意思是一个词是否由 k 个词组成)?有什么想法吗?

【问题讨论】:

标签: algorithm language-agnostic


【解决方案1】:

从中心开始拆分可能会更快产生结果。例如,对于报纸,您将首先尝试在“news paper”或“newsp aper”处进行拆分。如您所见,对于此示例,您会在第一次或第二次尝试时找到结果。如果没有找到结果,就向外搜索。请参阅下面的“弩”示例:

cros sbow
cro ssbow
cross bow

【讨论】:

    【解决方案2】:

    对于有两个单词的情况,只要考虑将单词分成两个的所有可能方法,然后检查每一半看它是否是一个有效的单词,就可以解决这个问题。如果输入字符串的长度为 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(nk),因为它试图将字符串的所有可能分区生成 k 个不同的片段。当然,这种最坏情况的行为不太可能发生,因为大多数可能的拆分最终不会形成任何单词。

    【讨论】:

      【解决方案3】:

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

      • 在字典中循环遍历字典中的每个单词并将结果保存到一个数组中,假设它为我提供了“new”、“paper”和“news”的结果。
      • 检查是否 new+paper==newspaper,检查是否 new+news==newspaper 等,直到找到返回的 paper+news==newspaper。

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

      不知道“你如何将它概括为 k”是什么意思。

      【讨论】:

      • 我很确定循环遍历像“报纸”这样的 9 个字母的单词会比遍历整个字典更快。
      • 对k进行泛化意味着检查一个词是否由k个词组成。
      猜你喜欢
      • 2014-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多