Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 以低内存占用存储大型词典的方法+;快速查找(在Android上)_Java_Android_Algorithm_Data Structures_Complexity Theory - Fatal编程技术网

Java 以低内存占用存储大型词典的方法+;快速查找(在Android上)

Java 以低内存占用存储大型词典的方法+;快速查找(在Android上),java,android,algorithm,data-structures,complexity-theory,Java,Android,Algorithm,Data Structures,Complexity Theory,我正在开发一个android文字游戏应用程序,它需要一个大的(约250000字的字典)可用。我需要: 合理快速的查找(例如,最好是恒定时间),有时需要每秒查找200次以解决字谜,可能需要在0.2秒内更频繁地查找20次以检查用户刚刚拼写的单词 编辑:查找通常会询问“是否在词典中?”。我也希望在单词中支持最多两个通配符,但这非常简单,只需生成通配符可能包含的所有字母并检查生成的单词(即26*26查找一个包含两个通配符的单词) 因为它是一款移动应用程序,所以使用尽可能少的内存,只需要少量的初始下

我正在开发一个android文字游戏应用程序,它需要一个大的(约250000字的字典)可用。我需要:

  • 合理快速的查找(例如,最好是恒定时间),有时需要每秒查找200次以解决字谜,可能需要在0.2秒内更频繁地查找20次以检查用户刚刚拼写的单词
编辑:查找通常会询问“是否在词典中?”。我也希望在单词中支持最多两个通配符,但这非常简单,只需生成通配符可能包含的所有字母并检查生成的单词(即26*26查找一个包含两个通配符的单词)

  • 因为它是一款移动应用程序,所以使用尽可能少的内存,只需要少量的初始下载就可以下载字典数据,这是最重要的
我第一次天真的尝试使用了Java的HashMap类,这导致了内存不足异常。我曾研究过使用android上可用的SQLLite数据库,但这似乎有些过分


什么是做我需要的事情的好方法?

你会想要某种类型的。我想也许a会很好。它们提供了非常快速的查找和较低的内存使用率。提供有关TST的更多信息。它还讨论了排序,因此并非所有内容都适用。可能更适用一些。正如文章所说,TSTs

结合数字化的时间效率 试与空间效率 二叉搜索树


如表所示,查找时间与使用哈希表非常相似。

我假设您希望检查给定单词是否属于字典

看一看

bloom过滤器可以执行“X是否属于预定义集”类型的查询,并且存储需求非常小。如果对查询的回答是肯定的,那么出错的概率很小(并且可以调整);如果对查询的回答是否定的,那么保证答案是正确的

根据维基百科的文章,你可能需要少于4MB的空间来存储250000个单词的字典,错误概率为1%


如果单词实际包含在字典中,bloom过滤器将正确回答“在字典中”。如果字典中没有这个词,布鲁姆过滤器可能会以很小的概率错误地给出“在字典中”的答案。

你也可以用更低级的方法实现你的目标。。。如果这是一个文字游戏,那么我怀疑你正在处理27个字母。因此,假设一个字母表不超过32个字母,即每个字母5位。通过使用5位/字母的普通编码,您可以将12个字母(12 x 5=60位)塞进一个Java长度

这意味着,实际上,如果单词长度不超过12个字母/单词,则可以将字典表示为一组Java长字符。如果您有250000个单词,那么这个集合的一个简单表示就是一个单独的、经过排序的long数组,它应该需要250000个单词x 8个字节/word=2000000~2MB内存。然后通过二进制搜索进行查找,考虑到数据集的小规模,这种搜索应该非常快(不到20次比较,因为2^20会将您带到100万以上)

如果单词的长度超过12个字母,那么I将把>12个字母的单词存储在另一个数组中,其中1个单词将以明显的方式由2个串联的Java长字符表示


注意:之所以这样做有效,而且可能比trie更节省空间,而且至少实现起来非常简单,是因为字典是常量。。。如果需要修改数据集,搜索树是好的,但是如果数据集是常数,则可以使用简单的二进制搜索方式运行。

也可以使用C和C++中的结构,而

< P>一种非常有效的存储目录的方法是(DWWG)。 以下是一些链接:

  • 源代码描述

我使用的设备基本上是从一个二进制压缩文件开始工作的,其拓扑结构类似于二叉树。在leafs中,您将拥有哈夫曼压缩文本。查找节点需要跳到文件的各个位置,然后只加载真正需要的部分数据。

正如“Antti Huima”试图存储字典单词所建议的,这是一个非常酷的想法。然后使用二进制搜索。

我的帖子原文中有一条评论说尝试占用了大量内存,但我删除了它,因为我不太确定。看了你的链接后我还是不确定。来自维基:“trie是以牺牲大小为代价优化速度的。”以及在现代实践中,三元搜索树通常被拒绝,取而代之的是哈希表。此外,还有其他方法来构造trie。例如,一个基数树trie,其中每个节点存储一个位字符串,并有两个子节点用于可能的下一个位,它可能比三元搜索树更紧凑,而不会太慢。“我发现了一个有趣的apache license trie Java实现:是的,我不确定它们在空间方面是否一定会更好,但有一些方法可以减少这种情况,例如折叠只有一个子代的节点。您可能还想看看我所知道的HAT-triesMost-trie实现,它们可以为您进行折叠。我想我只需要对一些进行基准测试。谢谢,我会看看帽子树。看起来很有趣。这是一个文字游戏,所以我需要100%肯定的答案,如果这个单词在字典里,或者用户会生气!Bloom过滤器可能会出现误报。如果你的游戏有时会接受字典中没有的单词,这是一个问题吗?啊,这是“误报是可能的,但误报是不可能的”。我想95%的时候,用户会提交实际的单词。这取决于一个虚假的单词被识破的频率,因为你不想让它成为游戏策略的一部分(这可能是一个有趣的游戏,尽管你试图通过看起来像真实单词的非单词潜行)!你可以调整