如何将文件内容视为String

时间:2011-05-21 18:49:59

标签: java file text dictionary

我正在创建一个使用字典的Scrabble游戏。为了提高效率,不是将整个字典(通过txt文件)加载到数据结构(Set,List等),而是有任何内置的java类可以帮助我将文件的内容视为String。

具体来说,我想做的是通过做一些像fileName.contains(word)这样简单的事情来检查游戏中的单词是否是字典中的有效单词,而不是使用内存效率低且使用列表的巨大列表。包含(字)。

你们对我能做什么有任何想法吗?如果字典文件必须是txt文件以外的其他内容(例如xml文件),我也可以尝试使用它。

注意:我不是在寻找http://commons.apache.org/io/api-1.4/org/apache/commons/io/FileUtils.html#readFileToString%28java.io.File%29

此方法不是Java API的一部分。

HashSet没有想到,我坚持认为所有contains()方法都使用了O(n)时间,感谢Bozho清除它,看起来我将使用HashSet。

4 个答案:

答案 0 :(得分:7)

我认为你最好的选择是将它们全部加载到内存中HashSet。那里contains(word)是O(1)。

如果您将其记录在内存中,那么将其String作为contains(..)进行调用的效率远低于HashSet

我必须提到另一个选项 - 有一个数据结构来表示字典 - 它被称为Trie。但是,您无法在JDK中找到实现。

一个非常粗略的计算表明,使用所有英文单词(100万),您将需要~12兆字节的RAM。这比JVM的默认内存设置少几倍。 (平均100万* 6个字母*每个字母2个字节= 12个百万字节,约为12兆字节)。 (好吧,也许存储哈希值更多)

如果您真的坚持不在内存中阅读它,并且想要扫描文件中的某个单词,那么您可以使用java.util.Scanner及其scanner.findWithHorizon(..)。但这样效率很低 - 我假设O(n)和I / O开销。

答案 1 :(得分:3)

虽然HashSet可能是一个完全可以接受的解决方案(参见Bozho的回答),但还有其他数据结构可以使用,包括Trie或Heap。

Trie的优点是,取决于实现细节,可以共享起始前缀字母(毕竟,trie也称为“前缀树”)。根据实施结构和数据,这实际上可能是也可能不是改进。

另一个选项,特别是在需要基于文件的访问时,是使用Heap - Java的PriorityQueue实际上是一个堆,但它不是基于文件的,所以这需要查找/创建一个实现

所有这些数据结构(以及更多)都可以实现为基于文件(使用更多IO 每次查找 - 实际上可能总体上更少 - 但节省内存)或实现直接(例如使用SQLite,让它做它的B-Tree事情)。 SQLite擅长于它可以是一个“常用工具”(曾经常用;-)在工具箱中;数据导入,检查和修改很容易,“它只是工作”。 SQLite甚至可用于功能较弱的系统,例如Android。

HashSet随Java免费提供,但没有标准的Trie或基于文件的Heap实现。我将从HashSet开始 - 推理:

  1. 字典= 5MB。
  2. 加载到HashSet中(假设有很多开销)= 20MB。
  3. 与其他事物相关的内存使用量=最小值(假定笔记本电脑/台式机)
  4. 使用HashSet实现的时间= 2分钟。
  5. 如果我认为HashSet不够好,我只会“丢失”2分钟: - )
  6. 快乐的编码。


    随机数据结构实现的链接(可能适用也可能不适用):

    • TernarySearchTrie读取平面文件(必须是专门构建的?)
    • TrieTree支持从平面文件创建Trie文件。不确定这个Trie是否可以从磁盘上运行。
    • FileHash使用文件备份的哈希。
    • HashStore另一个基于磁盘的哈希
    • WB B-Tree简单的B树实现/“数据库”
    • SQLite小型嵌入式RDBMS。
    • UTF8String可用于显着降低使用拉丁字典时使用HashSet<String>的内存要求。 (Java中的字符串使用UTF-16编码,该编码至少为两个字节/字符。)

答案 2 :(得分:1)

您需要压缩数据以避免存储所有这些字词。这样做的方法是树,其中节点是字母,叶子反映单词的结尾。这样您就不会存储重复数据,例如the there these,这些单词都具有相同的前缀。

有一种方法可以使此解决方案更加节省内存。 (提示:信件订单)

答案 3 :(得分:-1)

使用java.io.BufferedReader的readline()。返回一个字符串。

String line = new BufferedReader (new FileReader (file) ).readline ();