Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何检查是否可以在字典中找到所有子字符串_Algorithm_Search_Substring - Fatal编程技术网

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,并记住是否可以从端点匹配到端点的结果