<?php /** * Simple diff imlementation * Test example from http://en.wikipedia.org/wiki/Diff */ $orginal = "This part of the document has stayed the same from version to version. It shouldn't be shown if it doesn't change. Otherwise, that would not be helping to compress the size of the changes. This paragraph contains text that is outdated. It will be deleted in the near future. It is important to spell check this dokument. On the other hand, a misspelled word isn't the end of the world. Nothing in the rest of this paragraph needs to be changed. Things can be added after it."; $new = "This is an important notice! It should therefore be located at the beginning of this document! This part of the document has stayed the same from version to version. It shouldn't be shown if it doesn't change. Otherwise, that would not be helping to compress anything. It is important to spell check this document. On the other hand, a misspelled word isn't the end of the world. Nothing in the rest of this paragraph needs to be changed. Things can be added after it. This paragraph contains important new additions to this document."; // split them by newline $orginal = explode("/n", $orginal); $new = explode("/n", $new); // get the lcs information $lcs = lcs($orginal, $new); $orginalLcsPos = $lcs[1]; $newLcsPos = $lcs[2]; //append the end position to the array array_push($orginalLcsPos, count($orginal)); array_push($newLcsPos, count($new)); $from1 = $from2 = 0; for($i = 0; $i < count($orginalLcsPos); $i++) { $to1 = $orginalLcsPos[$i]; $to2 = $newLcsPos[$i]; if ($to1 - $from1 == 0 && $to2 - $from2 == 0) { // nothing happen } elseif($to1 - $from1 > 0 && $to2 - $from2 == 0) { // delete printf("%d,%dd/n", $from1, $to1 - 1); printout($orginal, $from1, $to1 - 1, '<'); } elseif($to1 - $from1 == 0 && $to2 - $from2 > 0) { // insert printf("%da%d,%d/n", $from1, $from2, $to2 - 1); printout($new, $from2, $to2 - 1, '>'); } else { // change printf("%d,%dc%d,%d/n", $from1, $to1 - 1, $from2, $to2 - 1); printout($orginal, $from1, $to1 - 1, '<'); echo "------------------/n"; printout($new, $from2, $to2 - 1, '>'); } $from1 = $to1 + 1; $from2 = $to2 + 1; } function printout($data, $from, $to, $sign) { for($i = $from; $i <= $to; $i++) { echo $sign.' '.$data[$i]."/n"; } } /** * Get the largest common subsequence * * @param $input1 * @param $input2 * @link http://en.wikipedia.org/wiki/Longest_common_subsequence_problem */ function lcs($input1, $input2) { $len1 = count($input1); $len2 = count($input2); for($i = 0; $i <= $len1; $i++) { $p[$i][0] = 0; $s[$i][0] = array(); $l1[$i][0] = array(); $l2[$i][0] = array(); } for($i = 0; $i <= $len2; $i++) { $p[0][$i] = 0; $s[0][$i] = array(); $l1[0][$i] = array(); $l2[0][$i] = array(); } for($i = 0; $i < $len1; $i++) { for($j = 0; $j < $len2; $j++) { if ($input1[$i] == $input2[$j]) { $p[$i+1][$j+1] = $p[$i][$j] + 1; $s[$i+1][$j+1] = array_merge($s[$i][$j], array($input1[$i])); $l1[$i+1][$j+1] = array_merge($l1[$i][$j], array($i)); $l2[$i+1][$j+1] = array_merge($l2[$i][$j], array($j)); } else { if ($p[$i][$j+1] > $p[$i+1][$j]) { $p[$i+1][$j+1] = $p[$i][$j+1]; $s[$i+1][$j+1] = $s[$i][$j+1]; $l1[$i+1][$j+1] = $l1[$i][$j+1]; $l2[$i+1][$j+1] = $l2[$i][$j+1]; } else { $p[$i+1][$j+1] = $p[$i+1][$j]; $s[$i+1][$j+1] = $s[$i+1][$j]; $l1[$i+1][$j+1] = $l1[$i+1][$j]; $l2[$i+1][$j+1] = $l2[$i+1][$j]; } } } } return array(implode("/n", $s[$i][$j]), $l1[$i][$j], $l2[$i][$j]); } 输出: 0a0,5 > This is an important > notice! It should > therefore be located at > the beginning of this > document! > 7,13c13,13 < compress the size of the < changes. < < This paragraph contains < text that is outdated. < It will be deleted in the < near future. ------------------ > compress anything. 16,16c16,16 < check this dokument. On ------------------ > check this document. On 23,23c23,27 < be added after it. ------------------ > be added after it. > > This paragraph contains > important new additions > to this document.