存储和检索DAWG数据结构以实现快速加载的最佳方式

时间:2010-11-23 22:14:25

标签: performance dictionary data-structures space-efficiency

我有一个500k +的单词表,我将其加载到DAWG数据结构中。我的应用程序适用于手机。我当然不希望重复所有的转换步骤,每次都将这个词表加载到DAWG中,因为它需要很多存储空间才能在手机上放置词表,并且每次都需要很长时间才能将它加载到DAWG中。所以,我正在寻找一种方法将数据存储到我的DAWG文件或数据库中,以便节省空间并允许我快速将其加载回我的DAWG数据结构。

我收到一条建议,我可以将每个节点存储在SQLite数据库中,但我不确定这是如何工作的,如果我这样做,我将如何快速检索它。我当然不希望运行大量查询。其他一些类型的存储方法会更好吗?我还收到了创建序列化文件或将其存储为位图的建议。

3 个答案:

答案 0 :(得分:2)

你基本上可以进行内存转储,只需使用偏移而不是指针(用Java术语,将所有节点放在一个数组中,并使用数组索引来引用一个节点)。

对于现代手机而言,500k似乎不会有问题,特别是DAWG已经非常有效。如果您对该文件进行mmap,即使它不适合内存,您也可以使用该数据结构。

答案 1 :(得分:1)

你有没有试过减少这个词表?如果可能,您是否只保存stam一词?

另一方面:你永远不应该重建数据结构,因为wordlist是常量。尝试使用像suggusted一样的内存转储。使用mmap进行文件,java序列化或pickle pickle技术,将现成的数据结构加载到内存中。

答案 2 :(得分:0)

我想,您正在使用DAWG快速搜索字典中的某些单词。 DAWG的搜索复杂度O(LEN)

很多年前,我开发了J2ME app并遇到了同样的问题。但在那个时代,手机无法提供这样的RAM内存量,存储500K +字符串)我使用的解决方案如下:

  1. 阅读所有单词,对它们进行排序,逐行输入一些文件 每个单词预先计算skipBytes。 - 此前的字节数 字。计算skipBytes是微不足道的。伪代码是 skipBytes[0]=words[0].bytesLen; for i=1 to n skipBytes[i]=skipBytes[i-1]+words[i].getBytesLength
  2. 当应用程序启动时,读取500k skipBytes到某个int数组。它 比500K字符串要小得多)
  3. 在字典中搜索单词 - 二进制搜索。想象一下,你是在排序的数组上执行它,而不是让array[i]RandomAccessFile.read(skipBytes[i])那样。谷歌Java随机存取文件我的pseucode当然是错误的,只是方向。
  4. 复杂性 - O(LEN*LOG(N)) =二进制搜索和比较字符串的日志是线性复杂性。 LOG(500000)~19,LEN~最差情况下的平均字数为50(奇妙的上限),因此搜索操作仍然非常快,只有~1000次操作将在微秒内完成。优点 - 内存使用量小。

    我应该提一下,万一用户在执行搜索时遇到网络应用,LOG(N)变得很重要,但如果您的应用仅为一个人提供服务,那么LOG(500000)如果有变化则不会有太大变化不在循环内执行)