0

我很确定这里可能已经进行了修改/类似的讨论,但我想从我这边提出我面临的可能解决方案的确切问题。然后我想听听你们的意见,什么是更好的方法或者我怎样才能批准我的逻辑。

问题 我有一个包含行的大文件。每行采用以下格式<weight>,<some_name>。现在我要做的是添加所有具有相同名称的对象的权重。问题是

  1. 我不知道some_name文件中存在的频率。它可能只出现一次或数以百万计的全部可能是它
  2. 它没有被订购
  3. 我正在使用文件流(特定于 java,但没关系)

解决方案1:假设我有巨大的内存,我打算做的是逐行读取文件并使用key我的hash_map中的名称。如果它已经在那里,总结它,否则添加。这将花费我mram(m = 文件中的行数),但整体处理速度会很快

解决方案 2:假设我没有巨大的 ram,我将分批进行。读取哈希表中的前 10,000 个,将其汇总并将其转储到文件中。对文件的其余部分执行此操作。完成文件处理后,我将开始阅读处理后的文件,并重复此过程以总结所有内容。

你们在这里有什么建议?

除了您的建议之外,我可以对文件进行并行文件读取吗?我可以在这里访问 FileInputStream,我可以使用 fileInputStream 来提高文件读取效率吗?

4

2 回答 2

2

第二种方法对您没有帮助:为了产生最终输出,您需要足够量的 RAM 来保存文件中的所有键,以及一个Integer表示计数的键。无论您是要迈出一大步还是一次迭代 10K 行,都不会改变您最终需要的占用空间。

以某种方式对键进行分区会有所帮助,例如按键的第一个字符。如果名称以字母开头,则处理该文件 26 次,第一次只取以开头的键的权重'A'并忽略所有其他键,第二次只取'B's,依此类推。这将使您最终得到 26 个不相交的文件。

另一种有效的方法是使用外部排序算法将无序文件转换为有序文件。这将让您遍历有序文件,计算总数,并将它们写入输出,即使不需要内存表。

就优化 I/O 而言,我建议使用类的newBufferedReader(Path path,Charset c)方法java.nio.file.Files:它为您提供了一个BufferedReader针对读取效率进行了优化的方法。

于 2013-08-13T17:00:09.587 回答
0

进行此计算时文件是静态的吗?如果是这样,那么您可以根据名称对文件进行磁盘排序并将连续条目相加。

于 2013-08-13T16:59:59.027 回答