[英]How to store vocabulary in an array more effectively?
我有一个词汇, a
, abandon
,..., z
。
出于某种原因,我将使用数组而不是Trie来存储它们。
因此,一个简单的方法可以是: wordA\\0wordB\\0wordC\\0...word\\0
但我认为还有一些更经济的记忆方法。
由于like
是likely
的子字符串,我们只能存储like
的第一个位置和长度而不是字符串本身。 因此,我们生成一个“大字符串”,其中包含词汇表中的每个单词,并使用position[i]
和length[i]
来获取第i
个单词。
例如,词汇表包含三个单词ab
, cd
和bc
。 我将abcd
构造为“大字符串”。
position[0] = 0, length[0] = 2
position[1] = 2, length[1] = 2
position[2] = 1, length[2] = 2
那么如何生成“大字符串”是这个问题的关键,有什么很酷的建议吗?
我认为问题类似于TSP问题(旅行商问题),这是一个NP问题。
您正在寻找的搜索关键字是“字典”。 即可用于存储单词列表的数据结构,并测试其他字符串是否存在于字典中。
你的想法比单独存储每个单词更紧凑,但远不如DAWG这样的好数据结构紧凑。 正如您所注意到的,如何最佳地选择如何重叠字符串并不明显。 你正在做的有点像无损压缩方案(如gzip)会做什么。 如果您不需要根据紧凑字典检查单词,可能只需使用gzip或LZMA来压缩排序单词列表。 让他们的算法找到冗余并紧凑地表示它。
我查看了字典中最近的一个SO答案引起了我的兴趣: 在关键服务器(数十亿个文件名)上对字符串进行内存限制的外部排序,并将重复数据组合在一起计算
对于不必动态添加新单词的字典,可以使用定向非循环字图表 。 您可以通过跟随图形节点将字符串与其匹配,直到您遇到没有边缘与下一个字符匹配的点,或者到达输入字符串的末尾并发现DAWG中的节点被标记为有效结束-of字。 (而不仅仅是一个只是某些单词前缀的子字符串)。 有一些算法可以在合理的时间内从一个简单的单词数组字典构建这些状态机。
当整个单词是另一个单词的子串,或者一个单词的结尾,另一个单词的开头时,您的方法只能利用冗余。 DAWG可以利用各处的常见子串,并且可以很快地匹配单词。 可能与二进制搜索数据结构的速度相当,尤其是 如果巨大的字符串太大而无法放入缓存中。 (一旦开始超过缓存大小,数据结构的紧凑性开始超过代码复杂性的速度。)
不太复杂但仍然有效的是Trie (或Radix Trie ),其中公共前缀被合并,但是稍后在单词中的公共子串不会再次收敛。
如果您根本不需要修改DAWG或Trie,则可以将其有效地存储在单个内存块中,而不是动态分配每个节点。 你没有说你为什么不想使用Trie,也没有承认其他数据结构的存在比普通的Trie更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.