2015-01-20 2 views
0

Я удалил 5000 файлов, сохраненных в отдельных файлах (0-4999.txt), теперь мне нужно найти в них дублирующийся контент. поэтому я сравниваю каждый файл друг с другом во вложенном цикле (ETA 82 часа). Этот подход, безусловно, займет несколько часов. Моя главная забота здесь - нет. итераций. Может ли кто-нибудь предложить лучший подход к сокращению итераций и сокращению времени?php: найти дублирующийся контент в файлах/вложенную петлю

текущий код: НИЗ алгоритм

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"; 
    } 
} 
+0

Может быть, [ 'расширение xdiff'] PECL (в HTTP : //php.net/manual/en/ref.xdiff.php) стоит посмотреть. Кажется мне, как действительный прецедент –

+0

@Elias: проблема не в соответствующем алгоритме, а в самом цикле, но я также проверю, обеспечивает ли xdiff лучшую скорость над ncd_new(). спасибо за предложение –

+0

Я просто понял, что разные 2 файла, и обработка diff (игнорирование _is_, _was_ и все такое) будет несколько более эффективной, чем то, что вы делаете сейчас. Или, по крайней мере: сохраните содержимое после 'preg_replace' где-нибудь (в памяти или на диске), чтобы избежать вызова' preg_replace' в тысячи раз бессмысленно –

ответ

0

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

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

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

, но по-прежнему медленно для моих требований.

Так я реализовал первую логику метода «НИЗ алго» на языке C, и он завершает задачу 5-10 секунд (в зависимости от среднего размера страницы)

0

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

Смежные вопросы