两个大文件的数组交集

时间:2015-09-17 21:15:18

标签: php arrays

我有两个文件,每个文件都有以下结构:

Gjdfnsdmfn141kj4
Fsndfdksjf1lkfjf
fjdksfn2m1kd1jk2
cmvlkm2kljo4jojj

这意味着逐行排列具有相同长度的行。这两个文件的重量约为1GB,这意味着约有40亿行。

我想计算两个文件中存在的行数。

发生的第一个问题是内存超出,然后一次缓冲两个文件,等等。我的想法是比较单个数据块,让我们说100k行,然后将交集保存到输出数组,并擦除temp数组等。

我设法编写的(伪)代码是这样的:

$output = [];

$first = [];
$fh1 = fopen("file1.txt", "r");
while (!feof($fh1)) {
   $first[] = fgets($fh1);
}

$chunk = 100000;

$fh2 = fopen("file2.txt", "r");
while (!feof($fh1)) {
   $count = 0;
   $lines = [];
   while(!feof($fh1) && (++count == $chunk)) {
      $lines[] = fgets($fh1);
   }
   intersection($fh1, $lines, $first);
}

function intersection($fh1, $lines, $first) {
   $output = array_merge($output, array_intersect($lines, $first));
}

但它有点慢,似乎总是会产生空array_intersect结果,并且只有在其中一个文件明显变小时才能工作。

我该如何以更好的方式做到这一点?

1 个答案:

答案 0 :(得分:2)

我会先使用external sorting算法对文件进行排序。 PHP可能不是理想的,因此现有的工具会更好,但谷歌似乎也有一些人在PHP之前做过这样的例子。

然后您可以打开两个(已排序)文件并一起浏览它们以查找匹配项。你只需向前移动一直到你有一行将在另一行中的当前行之后,然后切换(如果两者显示相同的行,则输出)。这样你就可以获得所有匹配但只需要传递一次文件。