给定一个字典,找出给定的单词是否可以由字典中的两个单词组成。例如。如果有“报纸”,你必须找到它是否可以用两个词来表达。 (本案中的新闻和文件)。我能想到的只是从头开始并检查当前字符串是否是一个单词。在这种情况下,检查n,ne,new,news .....如果当前字符串是有效字,则检查剩余部分。
另外,你如何概括它为k(意味着一个单词是由k个单词组成的)?有什么想法吗?
答案 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'。