我正在阅读动态编程问题。问题如下:
将长度为n的字符串转换为有效序列 话。假设有一个数据结构告诉您是否有字符串 在恒定时间内是一个有效的单词。
我在某种程度上解决了我的问题,但我读到的解决方案如下:
创建一个表T [N],表示如果子串,则T [i]为真 [0 ... i]可以分解成一系列有效的单词。如果是,则[[]]为真 存在j,0 <= j <= k-1其中T [j]为真并且S(j,k)是有效的 单词
这是DP的经典表述,但不是错吗?不应该是:
如果存在j,0 <=> j <= k-1,则T [i]为真,其中T [j]为真并且 S( j + 1 ,k)是有效字 OR S(0,i)是有效字?
否则我不知道如何构建表格,因为例如字符串:itsthe
如果我们不考虑T[2] = true
,我们将永远不会its
}是一个单词,下一个序列是the
,即S(2+1, N)
,j = 2
我在这儿吗?但是,我们怎样才能找到实际的词呢?
我为理解而做的示例代码(s.substring(i,j)
从java中的i including j-1
返回子字符串):
int i = 0
for(; i < s.length(); i++){
for(int j = 0; j > i; j++){
if(T[j] && dictionary.contains(s.substring(j + 1, i)){
T[i] = true;
break;
}
}
if(dictionary.contains(s.substring(0, i + 1)){
T[i] = true;
}
}
答案 0 :(得分:1)
你的所有更正都是正确的。
如果您想重建实际单词,请添加一个表格数组,该数组会告诉您用于将t[i]
设置为true
的最后一个字长。让我们调用这个数组L[i]
如果存在j,0 <=> j <= k-1,则T [i]为真,其中T [j]为真并且 S(j + 1,k)是有效字OR S(0,i)是有效字吗? 在第一个 如果您在后者L[i] = j
中设置了L[i] = i
。
然后添加您需要从L[n]
递回的结尾,其中n
是给定字符串的总长度。
答案 1 :(得分:0)
这取决于您的符号意味着什么,特别是选择子序列。你混合方括号和圆括号,“substring [0 ... i]”和“S(j + 1,k)”;我建议我们总是包括左手索引而不是右手索引。有时通过在左侧使用方括号和在右侧使用圆括号来明确这一点:S [0 ... i)。
如果我们这样做,那么原始措辞几乎正确;在i和k之间存在一些混淆,我认为这应该是相同的,并且i = 0的情况未得到正确处理。 (在相关的说明中,我认为你的修改也可能无法正确处理n = 0(空字符串)的情况。)
Create a table T[N] which says that T[i] is true if the substring S[0...i)
can be broken into a sequence of valid words. T[i] is true iff i = 0 OR
(there exists a j, 0<=j<i, where T[j] is true AND S[j...i) is a valid word).