php:在files/nested循环中查找重复内容
php: find duplicate content in files/nested looping
我已经抓取了 5000 个文件,将它们存储在单独的文件 (0-4999.txt) 中,现在我需要在其中找到重复的内容。所以我在嵌套循环(ETA 82 小时)中将每个文件相互比较。这种方法肯定需要数小时才能完成。我主要关心的是没有。的迭代。任何人都可以建议一种更好的方法来减少迭代并减少所花费的时间吗?
当前代码:NCD算法
function ncd_new($sx, $sy, $prec=0, $MAXLEN=9000) {
# NCD with gzip artifact correctoin and percentual return.
# sx,sy = strings to compare.
# Use $prec=-1 for result range [0-1], $pres=0 for percentual,
# For NCD definition see http://arxiv.org/abs/0809.2553
$x = $min = strlen(gzcompress($sx));
$y = $max = strlen(gzcompress($sy));
$xy= strlen(gzcompress($sx.$sy));
$a = $sx;
if ($x>$y) { # swap min/max
$min = $y;
$max = $x;
$a = $sy;
}
$res = ($xy-$min)/$max; # NCD definition.
if ($MAXLEN<0 || $xy<$MAXLEN) {
$aa= strlen(gzcompress($a.$a));
$ref = ($aa-$min)/$min;
$res = $res - $ref; # correction
}
return ($prec<0)? $res: 100*round($res,2+$prec);
}
遍历每个文件:
$totalScraped = 5000;
for($fileC=0;$fileC<$totalScraped;$fileC++)
{
$f1 = file_get_contents($fileC.".txt");
$stripstr = array('/\bis\b/i', '/\bwas\b/i', '/\bthe\b/i', '/\ba\b/i');
$file1 = preg_replace($stripstr, '', $f1);
// 0+fileC => exclude already compared files
// eg. if fileC=10 , start loop 11 to 4999
for($fileD=(0+$fileC);$fileD<$totalScraped;$fileD++)
{
$f2 = file_get_contents($fileD.".txt", FILE_USE_INCLUDE_PATH);
$stripstr = array('/\bis\b/i', '/\bwas\b/i', '/\bthe\b/i', '/\ba\b/i');
$file2 = preg_replace($stripstr, '', $f2);
$total=ncd_new($file1,$file2);
echo "$fileName1 vs $fileName2 is: $total%\n";
}
}
您可能想找到一种方法来区分可能的候选人和不太可能的候选人。
因此,也许有一种方法可以为每个文件计算一个值(比如:字数、句子/段落数……甚至可能是单个字母数),以预先识别不太可能的候选者。
如果你能做到这一点,你可以通过按这个计算出的数字对你的数组进行排序来减少比较的数量。
我尝试的另一个过程是:
- 从页面
删除html个标签
- 将 \s{2,} 替换为 \s,\n{2,} 替换为 \n,这样文本 b/w 每个标签都显示在一行中(几乎)
- 通过取一行来比较两个这样生成的文件,preg_matching,如果找到 -> 重复,否则将行分成单词数组,计算 array_intersect,如果计数是 70% 或更多行长 -> 重复。
效率很高,我可以在 ~10 分钟内比较 5000 个文件
但对我的要求来说仍然很慢。
所以我用C语言实现了第一个逻辑"ncd algo"方法,它用5-10秒完成任务(取决于平均页面大小)
我已经抓取了 5000 个文件,将它们存储在单独的文件 (0-4999.txt) 中,现在我需要在其中找到重复的内容。所以我在嵌套循环(ETA 82 小时)中将每个文件相互比较。这种方法肯定需要数小时才能完成。我主要关心的是没有。的迭代。任何人都可以建议一种更好的方法来减少迭代并减少所花费的时间吗?
当前代码:NCD算法
function ncd_new($sx, $sy, $prec=0, $MAXLEN=9000) {
# NCD with gzip artifact correctoin and percentual return.
# sx,sy = strings to compare.
# Use $prec=-1 for result range [0-1], $pres=0 for percentual,
# For NCD definition see http://arxiv.org/abs/0809.2553
$x = $min = strlen(gzcompress($sx));
$y = $max = strlen(gzcompress($sy));
$xy= strlen(gzcompress($sx.$sy));
$a = $sx;
if ($x>$y) { # swap min/max
$min = $y;
$max = $x;
$a = $sy;
}
$res = ($xy-$min)/$max; # NCD definition.
if ($MAXLEN<0 || $xy<$MAXLEN) {
$aa= strlen(gzcompress($a.$a));
$ref = ($aa-$min)/$min;
$res = $res - $ref; # correction
}
return ($prec<0)? $res: 100*round($res,2+$prec);
}
遍历每个文件:
$totalScraped = 5000;
for($fileC=0;$fileC<$totalScraped;$fileC++)
{
$f1 = file_get_contents($fileC.".txt");
$stripstr = array('/\bis\b/i', '/\bwas\b/i', '/\bthe\b/i', '/\ba\b/i');
$file1 = preg_replace($stripstr, '', $f1);
// 0+fileC => exclude already compared files
// eg. if fileC=10 , start loop 11 to 4999
for($fileD=(0+$fileC);$fileD<$totalScraped;$fileD++)
{
$f2 = file_get_contents($fileD.".txt", FILE_USE_INCLUDE_PATH);
$stripstr = array('/\bis\b/i', '/\bwas\b/i', '/\bthe\b/i', '/\ba\b/i');
$file2 = preg_replace($stripstr, '', $f2);
$total=ncd_new($file1,$file2);
echo "$fileName1 vs $fileName2 is: $total%\n";
}
}
您可能想找到一种方法来区分可能的候选人和不太可能的候选人。 因此,也许有一种方法可以为每个文件计算一个值(比如:字数、句子/段落数……甚至可能是单个字母数),以预先识别不太可能的候选者。 如果你能做到这一点,你可以通过按这个计算出的数字对你的数组进行排序来减少比较的数量。
我尝试的另一个过程是:
- 从页面 删除html个标签
- 将 \s{2,} 替换为 \s,\n{2,} 替换为 \n,这样文本 b/w 每个标签都显示在一行中(几乎)
- 通过取一行来比较两个这样生成的文件,preg_matching,如果找到 -> 重复,否则将行分成单词数组,计算 array_intersect,如果计数是 70% 或更多行长 -> 重复。
效率很高,我可以在 ~10 分钟内比较 5000 个文件
但对我的要求来说仍然很慢。
所以我用C语言实现了第一个逻辑"ncd algo"方法,它用5-10秒完成任务(取决于平均页面大小)