Java 如何将文件内容视为字符串
我正在创建一个使用字典的拼字游戏。为了提高效率,没有将整个字典(通过txt文件)加载到数据结构(集合、列表等)中,而是有任何内置java类可以帮助我将文件内容视为字符串 具体来说,我想做的是检查游戏中的单词是否是字典中的有效单词,方法是执行一些简单的操作,如fileName.contains(单词),而不是使用list.contains(单词)创建一个内存效率低下的庞大列表 你们知道我能做什么吗。如果字典文件必须是txt文件以外的文件(例如xml文件),我也愿意尝试 注意:我不是在找你Java 如何将文件内容视为字符串,java,file,text,dictionary,Java,File,Text,Dictionary,我正在创建一个使用字典的拼字游戏。为了提高效率,没有将整个字典(通过txt文件)加载到数据结构(集合、列表等)中,而是有任何内置java类可以帮助我将文件内容视为字符串 具体来说,我想做的是检查游戏中的单词是否是字典中的有效单词,方法是执行一些简单的操作,如fileName.contains(单词),而不是使用list.contains(单词)创建一个内存效率低下的庞大列表 你们知道我能做什么吗。如果字典文件必须是txt文件以外的文件(例如xml文件),我也愿意尝试 注意:我不是在找你 此方法不
此方法不是java API的一部分。 没有想到HashSet,我一直认为所有contains()方法都在使用O(n)次,多亏Bozho向我澄清了这一点,看起来我将使用HashSet。使用java.io.BufferedReader的readline()。返回一个字符串
String line = new BufferedReader (new FileReader (file) ).readline ();
使用java.io.BufferedReader的readline()。返回一个字符串
String line = new BufferedReader (new FileReader (file) ).readline ();
我认为最好的选择是将它们全部加载到内存中,在
哈希集中。那里包含(单词)
是O(1)
如果您不介意将其存储在内存中,那么将其作为String
调用contains(..)
比HashSet
效率低得多
我必须提到另一个选项-有一个数据结构来表示字典-它被称为。但是,在JDK中找不到实现
一个非常粗略的计算表明,对于所有英文单词(100万),您将需要约12兆字节的RAM。这比JVM的默认内存设置少几倍。(平均100万*6个字母*2个字节/字母=1200万字节,即~12兆字节)。(好吧,也许存储散列要多一点)
如果您确实坚持不在内存中读取它,并且希望扫描文件以查找给定的单词,那么您可以使用及其scanner.findWithHorizon(..)
。但这将是低效的-我假设O(n)和I/O开销。我认为最好的选择是将它们全部加载到内存中,在哈希集中。那里包含(单词)
是O(1)
如果您不介意将其存储在内存中,那么将其作为String
调用contains(..)
比HashSet
效率低得多
我必须提到另一个选项-有一个数据结构来表示字典-它被称为。但是,在JDK中找不到实现
一个非常粗略的计算表明,对于所有英文单词(100万),您将需要约12兆字节的RAM。这比JVM的默认内存设置少几倍。(平均100万*6个字母*2个字节/字母=1200万字节,即~12兆字节)。(好吧,也许存储散列要多一点)
如果您确实坚持不在内存中读取它,并且希望扫描文件以查找给定的单词,那么您可以使用及其scanner.findWithHorizon(..)
。但这将是低效的-我假设O(n)和I/O开销。您需要压缩数据以避免存储所有这些字。这样做的方法是一棵树,其中节点是字母,树叶反映单词的结尾。这样,您就不会存储重复的数据,例如这些词都有相同的前缀
有一种方法可以使此解决方案更高效地使用内存。(提示:字母顺序)您需要压缩数据,以避免存储所有这些单词。这样做的方法是一棵树,其中节点是字母,树叶反映单词的结尾。这样,您就不会存储重复的数据,例如这些词都有相同的前缀
有一种方法可以使此解决方案更高效地使用内存。(提示:字母顺序)虽然哈希集可能是完全可以接受的解决方案(参见Bozho的回答),但也可以使用其他数据结构,包括Trie或Heap
a的优点是,根据实现细节,可以共享起始前缀字母(trie毕竟也称为“前缀树”)。根据实现结构和数据,这可能是一种改进,也可能不是一种改进
另一种选择,特别是在需要基于文件的访问时,是使用--Java的PriorityQueue实际上是一个堆,但它不是基于文件的,因此需要查找/制作一个实现
所有这些数据结构(以及更多)都可以实现为基于文件的(每次查找都使用更多的IO——这实际上可能不太全面——但可以节省内存)或直接实现(例如,使用SQLite,让它做B树的事情)。SQLite的优势在于它可以成为工具箱中的“通用工具”(曾经常用;-);数据导入、检查和修改都很容易,而且“一切正常”。SQLite甚至用于功能较弱的系统,如Android
HashSet随Java“免费”提供,但没有标准的Trie或基于文件的堆实现。我将从HashSet开始——推理:
字典=5MB
加载到哈希集(假设大量开销)=20MB
与其他事物相关的内存使用=最小(假定为笔记本电脑/台式机)
使用HashSet实现的时间=2分钟
如果我认为哈希集不够好,我只会“损失”2分钟:-)
快乐编码
指向随机数据结构实现的链接(可能适用,也可能不适用):
- 在平面文件中读取(必须是专门构造的?)
- 支持从平面文件创建Trie文件。不确定此Trie是否在磁盘上工作李>
- 使用文件备份的哈希
- 另一个基于磁盘的散列
- 简单B-树实现