Algorithm 如何检查是否可以在字典中找到所有子字符串
我有一个问题,我想尽可能有效地解决。例如,, 我得到了一串单词:Algorithm 如何检查是否可以在字典中找到所有子字符串,algorithm,search,substring,Algorithm,Search,Substring,我有一个问题,我想尽可能有效地解决。例如,, 我得到了一串单词:a B C D,我有一本有5个词条的“字典”: A B C B D D E 字典告诉我输入字符串中可以包含哪些子字符串。我希望尽可能有效地检查整个输入字符串是否可以拆分为子字符串,以便在字典中找到所有子字符串 在本例中,可以通过将输入字符串拆分为A、bc和D 我想知道是否有一种更好的方法,而不仅仅是在所有可能的子字符串中使用暴力。我越少检查字典中是否有子字符串越好 如果没有可能的解决方案,就没有必要知道找不到哪些子字符串 谢谢。如
a B C D
,我有一本有5个词条的“字典”:
A
B C
B D
D
E
字典告诉我输入字符串中可以包含哪些子字符串。我希望尽可能有效地检查整个输入字符串是否可以拆分为子字符串,以便在字典中找到所有子字符串
在本例中,可以通过将输入字符串拆分为A
、bc
和D
我想知道是否有一种更好的方法,而不仅仅是在所有可能的子字符串中使用暴力。我越少检查字典中是否有子字符串越好
如果没有可能的解决方案,就没有必要知道找不到哪些子字符串
谢谢。如果您可以多次使用相同的子字符串,则有一个自然的动态规划解决方案 让n为字符串的大小。设v为大小为n的向量,使得v[i]=true当且仅当由原始字符串的(n-i)最后一个字符组成的子字符串可以用字典分解时。然后可以向后填充向量v,从最后一个索引开始,每一步减少i 在伪代码中:
Let D be your dictionnary
Let s be your string
Let n be the size of s
(Let s[i:j] denote the substring of s made by characters between i and j (inclusive))
Let v be a vector of size n+1 filled with zeros
Let v[n] = 1
For int i = n-1; i>=0; i--
For int j = i; j <=n-1; j++
If (s[i:j] is in D) and (v[j+1] is equal to 1)
v[i] = 1
Exit the for loop
Return v[0]
让D成为你的用语
让我们做你的绳子
设n为s的大小
(设s[i:j]表示由i和j(包括)之间的字符构成的s的子串)
设v是一个大小为n+1的向量,用零填充
设v[n]=1
对于int i=n-1;i> =0;我--
对于int j=i;我会用树代替字典。这将提高搜索速度并消除用于搜索的子树。您可以通过以下方法使其在O(N^2)
中运行
首先将所有字符串存储在trie中
第二,使用动态规划方法来解决您的问题。对于每个位置i
,我们将计算第一个i
符号的子字符串是否可以从字典(trie)中拆分为单词。为了简单起见,我们将使用动态规划的前瞻性方法
所以首先我们设置第一个0
符号的子串可以拆分。然后我们从0
迭代到N-1
。当我们谈到职位i
时,我们假设我们已经知道这个职位的答案。如果拆分是可能的,那么我们可以从这个位置开始,看看从这个位置开始的字符串在trie中。对于每个这样的字符串,尽可能标记其结束位置。通过使用trie,我们可以在每个外部循环迭代中O(N)
完成这项工作
t = trie of given words
ans = {false}
ans[0] = true
for i=0..N-1
if ans[i] // if substring s[0]..s[i-1] can be split to given words
cur = t.root
for j=i to N-1 // go along all strings starting from position i
cur=cur.child(s[j]) // move to the child in trie
// therefore, the position cur corresponds to string
// s[i]...s[j]
if cur.isWordEnd // if there is a word in trie that ends in cur
ans[j+1] = true // the string s[0]..s[j] can be split
your answer is in ans[N]
总时间是O(N^2)
您可以多次使用同一子字符串吗?一个简单的解决方案是使用字典构建一个trie树,然后使用该树匹配字符串并获得一组端点,然后从其中一个端点执行相同的操作,即DFS,并记住是否可以从端点匹配到端点的结果