Changeset 1021 for trunk/common


Ignore:
Timestamp:
03/01/09 17:42:38 (3 years ago)
Author:
gcosmin
Message:

Optimized longest common subsequence algorithm with O(N + M) memory and wrote it in C++
http://reviewboard.infoarena.ro/r/70/

Location:
trunk/common
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/common/diff.php

    r1018 r1021  
    8888 
    8989// compute longest common subsequence using dynamic programming 
    90 // FIXME: both time and memory complexity can be reduced 
    9190function lcs($a, $b) { 
    92     $N = mb_strlen($a); 
    93     $M = mb_strlen($b); 
    94     $C = array(array(2), array($M+1)); 
     91    $descriptorspec = array( 
     92        0 => array("pipe", "r"), 
     93        1 => array("pipe", "w"), 
     94        2 => array("pipe", "w"), 
     95    ); 
    9596 
    96     for ($i = 0; $i < 2; ++$i) 
    97         for ($j = 0; $j <= $M; ++$j) 
    98             $C[$i][$j] = ""; 
    99      
    100     for ($i = 1; $i <= $N; ++$i) { 
    101         for ($j = 1; $j <= $M; ++$j) { 
    102             if (mb_substr($a, $i-1, 1) == mb_substr($b, $j-1, 1)) { 
    103                 $C[$i%2][$j] = $C[($i-1)%2][$j-1].mb_substr($a, $i-1, 1); 
    104             } else if (mb_strlen($C[($i-1)%2][$j]) > mb_strlen($C[$i%2][$j-1])) { 
    105                 $C[$i%2][$j] = $C[($i-1)%2][$j]; 
    106             } else { 
    107                 $C[$i%2][$j] = $C[$i%2][$j-1]; 
    108             } 
    109         } 
     97    // run lcs process 
     98    $process = proc_open("iconv -f utf8 -t utf32 | " . IA_ROOT_DIR. 
     99        "/common/lcs" . " | iconv -f utf32 -t utf8", $descriptorspec, $pipes); 
     100    log_assert(is_resource($process), "Could not create process."); 
     101 
     102    // feed script to pipe 
     103    list($lcs_in, $lcs_out, $lcs_err) = $pipes; 
     104 
     105    fwrite($lcs_in, $a."\n"); 
     106    fwrite($lcs_in, $b."\n"); 
     107    fclose($lcs_in); 
     108 
     109    $result = fread($lcs_out, 10000); 
     110    fclose($lcs_out); 
     111 
     112    // check for errors 
     113    $errors = fread($lcs_err, 1000); 
     114    if ($errors) { 
     115        log_error($errors); 
    110116    } 
    111     return $C[$N%2][$M]; 
     117    fclose($lcs_err); 
     118 
     119    // clean-up 
     120    proc_close($process); 
     121 
     122    $result = trim($result, "\n"); 
     123 
     124    return $result; 
    112125} 
    113126 
Note: See TracChangeset for help on using the changeset viewer.