php: найти дублированный контент в файлах / вложенные циклы

Я скопировал 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";
    }
}

2 ответа

Решение

Другой процесс, который я попробовал, был:

  1. убрать теги html со страницы
  2. замените \s{2,} на \s, \n{2,} на \n, чтобы текст ч / б каждого тега был представлен в одной строке (почти)
  3. сравните два таких сгенерированных файла, взяв строку preg_matching, если она найдена -> duplicate, иначе разбейте строку на массив слов, рассчитайте array_intersect, если число составляет 70% или более от длины строки -> duplicate.

что было очень эффективно, и я мог сравнить 5000 файлов за ~10 минут

но все еще медленно для моих требований.

Итак, я реализовал первый логический метод "ncd algo" на языке C, и он выполняет задачу за 5-10 секунд (в зависимости от среднего размера страницы)

Возможно, вы захотите найти способ отличить вероятных кандидатов от неправдоподобных. Таким образом, возможно, есть способ, которым вы можете вычислить значение для каждого файла (скажем: количество слов, количество предложений / абзацев... может быть, даже количество отдельных букв), чтобы заранее определить вероятных кандидатов. Если бы вы могли добиться этого, вы могли бы уменьшить количество сравнений, упорядочив ваши массивы по этому вычисленному числу.

Другие вопросы по тегам