【问题标题】:Efficient way to iterate through a very large csv file with integers?用整数遍历一个非常大的 csv 文件的有效方法?
【发布时间】:2017-12-05 20:35:35
【问题描述】:

输入 1:一个包含一长串整数的 .csv 文件。例如:

1
10
23
2450
12
560
320
705
...

输入 2:一个包含整数列表的 .csv 文件,每个整数旁边都有一个空白位置

5 -
12 - 
15 -
13 -
350 -

输出:从输入 1 中找出输入 2 整数大于或等于的整数个数,并将该数字附加到 .csv 文件中。

问题在于这涉及 DNA 测序,输入 1 有超过一百万个数据条目。解决这个问题的有效方法是什么?

我的想法是将输入 1 的所有条目读入一个大数组并对其进行排序,但这似乎既低效又需要大量内存。任何指导将不胜感激。

编辑:

输出(与输入 2 相同的文件):

整数,计数

5 1
12 3
15 3
13 3
350 5 

【问题讨论】:

  • 如果输入 2 小得多,则将输入 2 中的整数存储在内存中,对它们进行排序,然后对于输入 1 中的每个 int,从输入 2 中取下一个更大的整数并将计数加 1。最后,对于输入 2 中的每个整数 x,您将获得位于 previos 和 x 之间的数字计数。要获得比x 更小的数字,只需将所有先前的计数相加即可。这只需要输入 2 的记忆,并且只需要输入 1 的线性时间,据我所知,这要长得多。
  • 我在您的“csv”文件中看不到任何逗号。它们不只是文本文件吗?
  • 我不明白你在做什么。请问你能展示一个输出的例子吗?
  • 你的意思是说“对应的输入2的整数大于[...]”?
  • 当您说“将数字插入 .csv 文件”时,您的意思是将数字 追加 到输入文件之一吗?将其附加到不同的文件?还是什么?

标签: java csv


【解决方案1】:

将第二个文件中的数字放入已排序的映射中,值为零:

TreeMap<Integer, Integer> counts = new TreeMap<>();
for (Integer i : fromFile2) {
  counts.put(i, 0);
}

然后,对于您从第一个文件中读取的每个数字,将计数增加到该数字:

for (Integer i : fromFile1) {
  counts.headMap(i).replaceAll((k, v) -> v + 1);
}

请注意,第二个循环不需要您将整个文件读入内存:您可以一次读取一个。

另外,请注意headMap(i) 返回键严格小于i 的条目。假设i &lt; Integer.MAX_VALUE,您可以简单地将该值加 1。

【讨论】:

  • 您甚至可以对此进行一些改进。对于从输入 1 读取的每个值,您只需增加输入 2 的 first 元素的记录计数,该元素至少与输入 2 一样大。在每个项目的输出中,将该项目的计数和所有较小的项目相加。这会提高渐近复杂度,除非输入 2 的大小受常数限制,在这种情况下它仍然会降低系数。
猜你喜欢
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2012-09-12
  • 2022-08-12
  • 1970-01-01
  • 2013-05-07
相关资源
最近更新 更多