【问题标题】:Double while loop to read a text file双while循环读取文本文件
【发布时间】:2011-10-26 00:28:18
【问题描述】:

是否可以使用双 while/for 循环读取文本文件?

我想做这样的事情:

for( String row1 = 0; row1 < file.length; row1++ ) {

   for( String row2 = row1 + 1; row2 < file.length; row2++ ){

       if( file[row1] == file[row2] ){
            // other code
       }

   }

}

我需要一个双循环,因为我必须在文件中找到包含 2.500.000 行的重复行。 我无法使用 Set 保存行,因为堆大小不足,如果我尝试增加它,我会收到此错误:“VM 初始化期间发生错误 无法为对象堆保留足够的空间 无法创建 Java 虚拟机..”(我有一个 Windows 7 64 位和 8 GB 内存)

提前致谢

【问题讨论】:

  • 您可能想要使用数据库。
  • 文件包含多少字节?
  • 你想对这些重复的行做什么?
  • 这不是一个很好的解决方案,您必须遍历内部循环中的所有行以查看它是否与外部循环中的行匹配。
  • @Sibbo 文件大小约为 430MB

标签: java


【解决方案1】:

对原始文件进行排序(您可以将其拆分并使用归并排序)。然后迭代查找 dup(如果 prev == cur,则您找到了一个 dup)。

【讨论】:

  • 但是这样堆问题的大小应该保持不变......还是我错了?
  • @Webman 不,这将解决堆大小问题,因为一旦将数据写入磁盘,您就不会保留对数据的引用。垃圾收集器将能够做它的事情。我添加了另一个答案,该答案更详细地解释了,并为您提供了一些指向实现细节和伪代码的链接。
【解决方案2】:

根据您的问题及其后的 cmets,您的目标是在大文件中查找重复项。最坏的情况是 O(N^2) - 将每个对象与每个其他对象进行比较。更好的解决方案是先对它们进行排序。

由于文件太大,您无法分配足够的内存在内存中对其进行排序,因此您需要使用不同的方法。 How could the UNIX sort command sort a very large file? 提供了一些实现的细节。一般问题是"external sorting"

来自维基百科页面的伪代码应该易于理解和实施。如果你真的很勇敢,你可以使用 Unix 排序命令和 Knuth 书的相应页面中的算法细节。

...最后,我还没有真正审查或测试过一些Googled code

【讨论】:

  • 我没有足够的时间研究它:(。我选择了数据库方式
  • 这不能回答问题。
【解决方案3】:

你可以这样做。但性能是 O(n²),不太好。另外,请注意不要使用==。这将检查两个实例是否是同一个对象,这与使用equals 不同。也许您可以为每一行计算一个哈希值并用它来检测可能的冲突。

【讨论】:

  • 性能并不重要:我只是想删除重复的行以获得一个新文件。
  • 然后我发现 Moishe 的解决方案会很好用。您可以解析文件,输出到两个一半大小的文件,然后递归地继续执行几次。然后从那些较小的文件开始合并排序回到较大的文件中。大量 IO,速度较慢,但​​内存使用量可以保持在最低限度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2018-04-17
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多