我收到了一个损坏的字符串,其中包含错误位置的空格和包含正确单词的字典。挑战是使用字典构造原始字符串。
For example :
Dictionary : ["how","are","you"]
Corrupted String : ho ware y ou
Original String : how are you
我正在考虑一种递归方法,因为每个角色都有两种可能性,它可以是一个新词或前一个词的一部分。 我正朝着正确的方向前进吗?这个问题有更好的方法吗?
答案 0 :(得分:4)
您应该删除所有空格,然后将字典中的单词与字符串的头部匹配,并递归检查字符串的尾部是否可以以相同的方式匹配。您希望递归函数返回所有匹配项,例如匹配的字符串的数组或树。我刚刚将它写入下面的打印输出,但你可以存储输出。
printAllMatches(String head, String tail)
if tail.equals("") print head and return
for each word w in dictionary
if w matches beginning of tail
printAllMatches(head + " " + w, tail - w) // remove w from front of tail
然后按printAllMatches("", stringWithoutSpaces)
调用该函数。在处理stringWithoutSpaces
的前面时,它会转移到head
。
答案 1 :(得分:3)
假设我们只想找到一个可能的答案。
递归是一种很好的使用方法。就像这样:
S = Corrupted String . replace(' ', '') // remove all [:space:]
def recursive(position):
if position == len(S): // A
return True // we found a solution!
for i in range(1, len(S) - position + 1):
if S[position: poition + i] in Dictionary: // B
if recursive(position + i):
return True
else:
break
// Find nothing, just return False
return False
recursive(0)
好的,我们现在可以找到答案,但是Big(O)是什么?
此外,我们有两个职位要加速:
一个。当我们查找单词是否在字典中时,我们可以使用trie-tree(http://en.wikipedia.org/wiki/Trie)来加速。所以我们每次都避免从红黑树中寻找它
B中。我们应该记住计算出的答案: 动态编程是一个很好的解决方案,因为你现在使用递归,你可以使用动态编程memoization [What is the difference between memoization and dynamic programming?
现在,复杂性是O(n * k)
答案 2 :(得分:0)
从字符串中删除空格后,我们可以使用动态编程来检查是否可以将字符串分解为字典中的单词。
下面是相同的C ++代码 -
void printOriginalString(string s, unordered_set<string> &dict)
{
int len = s.size();
bool res[len+1];
fill(res,res+len,0);
int i,j;
res[0] = true;
for(i=1;i<=len;i++)
{
for(j=0;j<i;j++)
{
res[i] = res[j] && (dict.find(s.substr(j,i-j))!=dict.end()); //if both prefix and suffix present in dictionary
if(res[i]) //found the word
break;
}
}
for(i=0;i<len;i++) //print the original string
{
if(res[i])
cout<<" ";
cout<<str[i];
}
}