String 用于检索字符串中的单词的数据结构

String 用于检索字符串中的单词的数据结构,string,data-structures,matching,String,Data Structures,Matching,我昨天提出了这个问题(),但我意识到这种方法可能是错误的 我需要的应该是一个数据结构,允许我存储字符串,并检索其中包含公共单词的所有字符串。不幸的是,我等不及了,用户已经输入了所有的单词,但我必须依靠前缀 例如,如果我有字符串“This is a string in the structure”和“Binary tree data structure”,并且作为输入,像“stru”这样的前缀,它们都必须在输出中 有什么有用的方法吗 这在很大程度上取决于列表中有多少字符串。如果您的列表不是很大,那

我昨天提出了这个问题(),但我意识到这种方法可能是错误的

我需要的应该是一个数据结构,允许我存储字符串,并检索其中包含公共单词的所有字符串。不幸的是,我等不及了,用户已经输入了所有的单词,但我必须依靠前缀

例如,如果我有字符串“This is a string in the structure”和“Binary tree data structure”,并且作为输入,像“stru”这样的前缀,它们都必须在输出中


有什么有用的方法吗

这在很大程度上取决于列表中有多少字符串。如果您的列表不是很大,那么您可以在用户输入第一个字符时执行简单的顺序搜索,然后在搜索结果中搜索后续搜索

例如,如果列表中有1000个字符串,并且用户类型为
's'
。您搜索原始列表,最终得到包含该字母的623个单词的列表。调用该列表
S

然后用户键入
't'
,然后您搜索
S
子字符串
“st”
。调用结果
ST

您将以这种方式继续,进行顺序搜索并对列表进行排序。它看起来像这样:

// search in initial list of strings for first character
results = new list
for each string in list
    if string.Contains("s")
        Add string to results

// for subsequent characters the user types
newResults = new list
for each string in results
    if string.Contains("st")
        Add string to newResults
results = newResults
名单很快就会变小。当你认为英语中最常见的二重词“Th”出现在大约3.8%的单词中时,很可能只有在两个字符被键入之后,你的列表中就有少于40个项目出现在开头1000。按顺序搜索将非常快。向用户显示结果所需的时间比搜索列表所需的时间更长

即使您最初的字符串列表中有100万项,用户可能也不会注意到输入的第一个字符有延迟。如果以增量方式显示结果,而不是在显示任何内容之前等待搜索整个列表,则情况尤其如此

通过创建第一个字符的索引,可以潜在地加快速度。也就是说,为字符串列表中包含的每个字符创建一个字典条目。它将是
字典
。因此,如果用户键入
“s”
,您将得到以下列表:

List<string> startingList = _dict['s'];
List startingList=_dict['s'];
然后使用前面的算法,从该列表开始

这可以加快您的初始搜索速度,但需要占用大量内存。除非您有一个非常大的初始字符串列表,否则不值得这么做

有关更多详细信息,请参阅

附加信息 如果要处理大量字符串,可能需要构建前缀树,但要限制其深度。例如,构建一个最大深度为3或4个字符的前缀树,然后使用上面显示的顺序方法。这将比一个完整的前缀树占用更少的内存,并且应该表现得很好。当您达到四个字符时,包含该子字符串的行数应该非常少

您应该编写代码来分析数据中的n克计数。查看您有多少个不同的二元图,以及与一个二元图匹配的最大行数。对三叉图、4克图等也要这样做,以确定你的截止点。例如,如果您发现没有任何4-gram具有超过1000条匹配行,那么您可能应该将前缀树限制为四个级别,然后使用顺序技术。在那之后真的没有必要创建完整的前缀树。尽管您可以创建完整的前缀树,然后将HapAxis折叠为单个节点。最终得到的基本上是一个有向无环单词图


不过,请记住,您是在响应用户输入。所以节省几毫秒并不重要。用户不会注意到20毫秒响应时间和5毫秒响应时间之间的差异。代码不一定要“尽可能快”,而是“足够快*供用户使用。如果您记住这一点,您可以创建一个使用更少内存的更简单的解决方案。

也许可以查找
trie
:是的,这是我想到的第一个数据结构,但您的输出只有以输入中给定的前缀开头的字符串。。。我是否应该以这种方式修改结构?您不受存储在trie中的内容的限制。存储所有后缀也是一种选择。我认为你的推理是正确的。不要在不需要的时候使用复杂的数据结构。不幸的是,我必须处理大量字符串。我正在考虑使用一种混合方法,使用前缀/基数树存储字符串中的所有术语,对于每个术语,我都有包含它的字符串列表。这有意义吗?这似乎是一个非常好的方法!我会试试这个:)