Algorithm 检查字符串是否由子字符串列表生成的算法
您将获得一个字符串和一个字符串数组。如何快速检查是否可以通过连接数组中的一些字符串来构建此字符串 这是一个理论问题,出于实际原因,我不需要它。但我想知道,是否有一些好的算法 编辑 阅读一些答案,我注意到,这可能是NP完全问题。即使找到字符串的子集,它们的长度也会相同,因为给定的字符串是一个经典的子集和问题 所以我想这个问题没有简单的答案 编辑 现在看来,这毕竟不是一个NP完全问题。这就更酷了:-) 编辑 我提出了一个通过一些测试的解决方案:Algorithm 检查字符串是否由子字符串列表生成的算法,algorithm,string,substring,Algorithm,String,Substring,您将获得一个字符串和一个字符串数组。如何快速检查是否可以通过连接数组中的一些字符串来构建此字符串 这是一个理论问题,出于实际原因,我不需要它。但我想知道,是否有一些好的算法 编辑 阅读一些答案,我注意到,这可能是NP完全问题。即使找到字符串的子集,它们的长度也会相同,因为给定的字符串是一个经典的子集和问题 所以我想这个问题没有简单的答案 编辑 现在看来,这毕竟不是一个NP完全问题。这就更酷了:-) 编辑 我提出了一个通过一些测试的解决方案: def can_build_from_substrin
def can_build_from_substrings(string, substrings):
prefixes = [True] + [False] * (len(string) - 1)
while True:
old = list(prefixes)
for s in substrings:
for index, is_set in enumerate(prefixes):
if is_set and string[index:].startswith(s):
if string[index:] == s:
return True
prefixes[index + len(s)] = True
if old == prefixes: # nothing has changed in this iteration
return False
我相信时间是
O(n*m^3)
,其中n
是子字符串的长度
,m
是字符串的长度
。你觉得怎么样?我会这样做的
生成所有排列是一项处理器繁重的任务,因此如果您可以减少“n”(输入大小),您将获得相当大的效率。这肯定不快,但您有一个想法:
- 迭代所有字符串,检查目标字符串是否以其中任何一个“开始”
- 取目标字符串开头的最长字符串,将其从列表中删除,并将其从主字符串中修剪
- 冲洗,重复
- 当您发现字符串是目标的头部时,将其推到列表中。建立列表后,您自然会尝试目标中最大的“头”
- 当你发现你试过的头与剩下的不匹配时,试试下一个最好的头
这样,最终您将探索解决方案的整个空间。对于每一个候选人的头部,你都会尝试每一个可能的尾部。两个选项在脑海中闪现,但它们看起来都不是很优雅 1) 蛮力:像密码生成器一样操作,如word1+word1+word1>word1+word1+word2>word1+word1+word3等 诀窍在于长度,因此你必须尝试2个或更多单词的所有组合,而你不知道在哪里设置限制。非常耗时
2) 取有问题的字符串,对每个单词一次查找1个。可能会检查长度,如果大于0,请再次检查。继续这样做,直到你达到零它找不到任何更多的结果。如果你打0,那就是赢,如果不是输的话。我认为这种方法比第一种要好得多,但我想有人会有更好的建议。在我看来,一个问题可以通过简单的数组线性遍历和比较来解决。但是,可能会有多次通过。您可以设计一种策略来最小化传递。例如,在第一个过程中构造原始字符串的所有子字符串的子数组。然后线性地尝试不同的变化。这里有一个大概的想法应该是可行的
一种可能的改进方法是首先迭代所有子字符串,并抛出主字符串中不包含的任何子字符串。然后完成上述步骤。注意:我假设您可以多次使用每个子字符串。您可以通过更改子问题的定义方式,将解决方案概括为包含此限制。这将对空间和预期运行时间产生负面影响,但问题仍然存在。 这是一个动态规划问题。(这是一个很好的问题!) 如果可以使用子字符串列表
W
编写字符串s
,那么让我们将composable(s,W)
定义为true
S
在以下情况下才可组合:
S
以w
中的子字符串w
开头w
之后的S
的其余部分也是可组合的COMPOSABLE(S, W):
return TRUE if S = "" # Base case
return memo[S] if memo[S]
memo[S] = false
for w in W:
length <- LENGTH(w)
start <- S[1..length]
rest <- S[length+1..-1]
if start = w AND COMPOSABLE(rest, W) :
memo[S] = true # Memoize
return memo[S]
受@cnicutars启发,答案:
- 函数
可能(数组A、字符串s)
- 如果
为空,则返回trues
- 计算
中作为A
前缀的所有字符串的数组s
P
- 如果
为空,则返回falseP
- 对于
中的每个字符串p
:p
- 如果
返回true可能(A去掉p,s去掉前缀p)
- 如果
- 返回错误
- 如果
Find all z occurrences of the patterns P1..Pn of total length m
enter code hereas substrings in O(m + z) time.