String 在字典中组合单词以匹配单个单词

String 在字典中组合单词以匹配单个单词,string,algorithm,dictionary,String,Algorithm,Dictionary,我正在研究一个问题,我需要检查字典中有多少单词可以组合起来匹配一个单词 例如: 给定字符串“hellogoodsir”和字典:{hello,good,sir,go,od,e,l},目标是找到构成字符串的所有可能组合 在这种情况下,结果将是hello+good+sir,以及hello+go+od+sir,结果是使用了3+4=7个单词,或1+1=2个组合 我想到的只是将所有以第一个字符(本例中为“h”)开头的单词放在一个hashmap(startH)中,其余的放在另一个hashmap(endH)中。

我正在研究一个问题,我需要检查字典中有多少单词可以组合起来匹配一个单词

例如:
给定字符串“hellogoodsir”和字典:{hello,good,sir,go,od,e,l},目标是找到构成字符串的所有可能组合

在这种情况下,结果将是hello+good+sir,以及hello+go+od+sir,结果是使用了3+4=7个单词,或1+1=2个组合

我想到的只是将所有以第一个字符(本例中为“h”)开头的单词放在一个hashmap(startH)中,其余的放在另一个hashmap(endH)中。然后,我检查startH hashmap中的每个单词,并检查“hellogoodsir”是否包含新词(start+end),其中end是endH hashmap中的每个单词。如果是,我检查它是否等于要匹配的单词,然后用每个单词的数字值递增计数器。如果它包含它,但不等于它,我将使用新词(即start+end)调用相同的方法(递归),并继续尝试将end hashmap中的任何词附加到新词以获得匹配

对于大量单词(以及要匹配的长字符串),这显然非常慢。有没有更有效的方法来解决这个问题?

据我所知,这是一个O(n^2)算法,但我相信这可以做得更快。

让我们从您的解决方案开始。它不是线性时间,也不是二次时间,它实际上是指数时间。反例表明:

word = "aaa...a"
dictionary = {"a", "aa", "aaa", ..., "aa...a"}
因为你的解决方案是通过每一个可能的匹配,在这个例子中,这样的匹配是指数数量的-解决方案是指数时间

但是,通过以下递归公式,可以更有效地实现这一点(二次时间最坏情况):

D[0] = 1 # 
D[i] = sum { D[j] | word.Substring(i,j) is in the dictionary | 0 <= j < i }

我的建议是使用一个。根目录下的节点将是
h
g
s
o
e
l
。您还需要用于终止字符的节点,以区分
go
good

要查找所有匹配项,请使用广度优先搜索方法。您要跟踪的状态由以下组成:搜索字符串中的当前索引、树中的当前节点以及迄今为止使用的单词列表

初始状态应为0,根,[]

当状态列表不为空时,将下一个状态出列,然后查看索引是否与节点子节点的任何键匹配。如果是,请修改状态的副本并将其排队。此外,如果任何子级是终止字符,请执行相同的操作,将单词添加到状态中的列表中


我不确定这个算法的O(n)时间,但它应该快得多

我不是100%确定您的建议,但似乎您正在尝试实际迭代所有“不同的构建”(即,对于每个可能的解决方案,积极地在树中找到其结尾)。因为它们的数量是指数级的——这是在指数级的时间内完成的。
dictionary = {hello, good, sir, go, od, e, l}
string = "hellogoodsir"
D[0] = 1
D[1] = 0 (no substring h)
D[2] = 0 (no substring he, d[1] = 0 for e)
...
D[5] = 1 (hello is the only valid string in dictionary)
D[6] = 0 (no dictionary string ending with g)
D[7] = D[5], because string.substring(5,7)="go" is in dictionary
D[8] = 0, no substring ending with "oo"
D[9] = 2: D[7] for "od", and D[5] for "good"
D[10] = D[11] = 0 (no strings in dictionary ending with "si" or "s")
D[12] = D[7] = 2 for substring "sir"