我在接受采访时被问到了问题。我无法弄清楚如何处理这个问题。请指导我。
问题:如何知道一个字符串是否可以被分割为两个字符串 - 比如breadbanana可分段为面包和香蕉,而breadbanan则不是。您将获得一个包含所有有效单词的字典。
答案 0 :(得分:13)
在字典中构建trie个单词,这样可以加快搜索速度。 根据输入字符串的以下字母搜索树。当您在树中找到一个单词时,递归地从输入字符串中该单词后面的位置开始。如果到达输入字符串的末尾,就会发现一个可能的碎片。如果你遇到困难,请回来并递归尝试另一个词。
编辑:对不起,错过了这个事实,一定只有两个字。 在这种情况下,将递归深度限制为2。2个单词的伪代码为:
T = trie of words in the dictionary
for every word in T, which can be found going down the tree by choosing the next letter of the input string each time we move to the child:
p <- length(word)
if T contains input_string[p:length(intput_string)]:
return true
return false
假设您可以转到O(1)
(子项的ascii索引)中的trie中的子节点,您可以在O(n+p)
中找到输入字符串的所有前缀,其中p
是前缀的数量,n
是输入的长度。上限是O(n+m)
,其中m
是字典中的单词数。检查包含将O(w)
,其中w
是单词的长度,其上限为m
,因此算法的时间复杂度为O(nm)
,因为O(n)
在所有找到的单词之间的第一阶段分发。
但是因为我们在第一阶段找不到n
个以上的单词,所以复杂性也仅限于O(n^2)
。
所以搜索复杂度为O(n*min(n, m))
在此之前,您需要构建将使用O(s)
的trie,其中s
是字典中单词长度的总和。其上限为O(n*m)
,因为每个单词的最大长度为n
。
答案 1 :(得分:4)
您浏览字典并将每个字词作为子字符串与原始字词进行比较,例如“breadbanana”。如果第一个术语与第一个子字符串匹配,则将第一个术语从原始搜索术语中删除,并将下一个字典条目与原始术语的其余部分进行比较......
让我试着在java中解释一下: e.g。
String dictTerm = "bread";
String original = "breadbanana";
// first part matches
if (dictTerm.equals(original.substring(0, dictTerm.length()))) {
// first part matches, get the rest
String lastPart = original.substring(dictTerm.length());
String nextDictTerm = "banana";
if (nextDictTerm.equals(lastPart)) {
System.out.println("String " + original +
" contains the dictionary terms " +
dictTerm + " and " + lastPart);
}
}
答案 2 :(得分:1)
最简单的解决方案:
在每对连续字符之间拆分字符串,并查看两个子字符串(分割点的左侧和右侧)是否在字典中。
答案 3 :(得分:0)
一种方法可能是:
Put all elements of dictionary in some set or list
现在你可以使用contains
&amp; substring
函数用于删除与字典匹配的单词。如果在结尾字符串为null - &gt;字符串可以被分段,否则不是。你也可以照顾好计数。
答案 4 :(得分:0)
public boolean canBeSegmented(String s) {
for (String word : dictionary.getWords()) {
if (s.contains(word) {
String sub = s.subString(0, s.indexOf(word));
s = sub + s.subString(s.indexOf(word)+word.length(), s.length()-1);
}
return s.equals("");
}
}
此代码检查您的给定String是否可以完全分段。它会检查字典中的单词是否在您的字符串中,然后对其进行跟踪。如果你想在这个过程中对它进行分段,你必须按照它们在单词中的顺序对减去的sementents进行排序。
只需两个单词就可以了:
public boolean canBeSegmented(String s) {
boolean wordDetected = false;
for (String word : dictionary.getWords()) {
if (s.contains(word) {
String sub = s.subString(0, s.indexOf(word));
s = sub + s.subString(s.indexOf(word)+word.length(), s.length()-1);
if(!wordDetected)
wordDetected = true;
else
return s.equals("");
}
return false;
}
}
此代码检查一个Word,如果String中有另一个单词,只有这两个单词,则返回true,否则返回false。
答案 5 :(得分:0)
这只是一个想法,如果你想要
,你可以更好地实现它package farzi;
import java.util.ArrayList;
public class StringPossibility {
public static void main(String[] args) {
String str = "breadbanana";
ArrayList<String> dict = new ArrayList<String>();
dict.add("bread");
dict.add("banana");
for(int i=0;i<str.length();i++)
{
String word1 = str.substring(0,i);
String word2 = str.substring(i,str.length());
System.out.println(word1+"===>>>"+word2);
if(dict.contains(word1))
{
System.out.println("word 1 found : "+word1+" at index "+i);
}
if(dict.contains(word2))
{
System.out.println("word 2 found : "+ word2+" at index "+i);
}
}
}
}