-
<?php
-
class DiffModel{
-
private $flip = false;
-
private $arr1 = null;
-
private $arr2 = null;
-
private $size1 = null;
-
private $size2 = null;
-
private $ses = null;
-
-
private $patharr=null;
-
const SAME=0;
-
const ADD=1;
-
const DEL=2;
-
-
public function __construct($article1="", $article2=""){
-
if(is_array($article1) and is_array($article2)){
-
$this->setArray($article1, $article2);
-
}else{
-
$this->setArticles($article1, $article2);
-
}
-
}
-
-
public function setArticles($article1, $article2){
-
if(strlen($article1)> strlen($article2)){
-
$this->arr1 = empty($article1) ? array() : mb_str_split($article1);
-
$this->arr2 = empty($article2) ? array() : mb_str_split($article2);
-
-
$this->size1 = count($this->arr1);
-
$this->size2 = count($this->arr2);
-
$this->flip = true;
-
}else{
-
$this->arr1 = empty($article2) ? array() : mb_str_split($article2);
-
$this->arr2 = empty($article1) ? array() : mb_str_split($article1);
-
-
$this->size1 = count($this->arr1);
-
$this->size2 = count($this->arr2);
-
$this->flip = false;
-
}
-
}
-
-
public function setArray($arr1, $arr2){
-
if(count($arr1)> count($arr2)){
-
$this->arr1 = $arr1;
-
$this->arr2 = $arr2;
-
-
$this->size1 = count($this->arr1);
-
$this->size2 = count($this->arr2);
-
$this->flip = true;
-
}else{
-
$this->arr1 = $arr2;
-
$this->arr2 = $arr1;
-
-
$this->size1 = count($this->arr1);
-
$this->size2 = count($this->arr2);
-
$this->flip = false;
-
}
-
-
}
-
-
public function diff(){
-
-
$offset = $this->size2 + 1;
-
-
$this->patharr = array();
-
-
$fp = array_fill(0, $this->size1 + $this->size2 + 3, -1);
-
$delta = $this->size1 - $this->size2;
-
-
$p=0;
-
for(; $fp[$delta + $offset] <$this->size1; $p++){
-
for($k = -$p; $k <$delta; $k++){
-
$fp[$k + $offset] = $this->snake($k, $offset, $fp);
-
}
-
-
for($k = $delta + $p; $k>= $delta; $k--){
-
$fp[$k + $offset] = $this->snake($k, $offset, $fp);
-
}
-
-
}
-
-
return $delta + 2*($p - 1);
-
}
-
-
public function getDiff(){
-
$ind = $this->size2 + $this->size1*($this->size2+1);
-
$item = array(-1, $this->size2, $this->size1);
-
$this->ses = array();
-
do{
-
switch($this->patharr[$ind][0]){
-
case (self::ADD):
-
if($item[0] != $this->patharr[$ind][0]){
-
$this->ses[] = array($this->flip ? self::ADD : self::DEL, $this->patharr[$ind][1], $item[1] - $this->patharr[$ind][1]);
-
}else{
-
$this->ses[count($this->ses)-1][1] = $this->patharr[$ind][1];
-
$this->ses[count($this->ses)-1][2] += $item[1] - $this->patharr[$ind][1];
-
}
-
//echo sprintf("add %3d-%3d %s\n", $this->patharr[$ind][1], $item[1], mb_substr($this->article2, $this->patharr[$ind][1], $item[1] - $this->patharr[$ind][1], "utf-8"));
-
break;
-
case (self::DEL):
-
if($item[0] != $this->patharr[$ind][0]){
-
$this->ses[] = array($this->flip ? self::DEL : self::ADD, $this->patharr[$ind][2], $item[2] - $this->patharr[$ind][2]);
-
}else{
-
$this->ses[count($this->ses)-1][1] = $this->patharr[$ind][2];
-
$this->ses[count($this->ses)-1][2] += $item[2] - $this->patharr[$ind][2];
-
}
-
//echo sprintf("del %3d-%3d %s\n", $this->patharr[$ind][2], $item[2], mb_substr($this->article1, $this->patharr[$ind][2], $item[2] - $this->patharr[$ind][2], "utf-8"));
-
break;
-
case (self::SAME):
-
if($item[0] != $this->patharr[$ind][0]){
-
$this->ses[] = array(self::SAME, $this->patharr[$ind][1], $item[1] - $this->patharr[$ind][1]);
-
}else{
-
$this->ses[count($this->ses)-1][1] = $this->patharr[$ind][1];
-
$this->ses[count($this->ses)-1][2] += $item[1] - $this->patharr[$ind][1];
-
}
-
//echo sprintf("sam %3d-%3d %s\n", $this->patharr[$ind][1], $item[1], mb_substr($this->article2, $this->patharr[$ind][1], $item[1] - $this->patharr[$ind][1], "utf-8"));
-
break;
-
}
-
-
$item = $this->patharr[$ind];
-
$ind = $this->patharr[$ind][1] + $this->patharr[$ind][2]*($this->size2+1);
-
-
}while($ind> 0);
-
-
$this->ses = array_reverse($this->ses);
-
return $this->ses;
-
-
}
-
-
private function snake($k, $offset, &$fp){
-
$y=0;
-
if($fp[$k-1 + $offset] + 1> $fp[$k+1+$offset]){
-
$y = $fp[$k-1 + $offset] + 1;
-
//$this->patharr[($y-$k) + $y*($this->size2+1)] = array($y-$k,$y-1);
-
$this->patharr[($y-$k) + $y*($this->size2+1)] = array(self::DEL, $y-$k,$y-1);
-
}else{
-
$y = $fp[$k+1 + $offset];
-
$this->patharr[($y-$k) + $y*($this->size2+1)] = array(self::ADD, $y-$k-1, $y);
-
}
-
-
$x = $y-$k;
-
$sx = $x;
-
$sy = $y;
-
-
while($x <$this->size2 and $y <$this->size1 and $this->arr2[$x] == $this->arr1[$y]){
-
$x++;
-
$y++;
-
}
-
-
if(!($x == $sx and $y == $sy) )$this->patharr[$x+$y*($this->size2+1)] = array(self::SAME, $sx,$sy);
-
-
return $y;
-
}
-
-
}
-
?>
One Response for "o(np)のdiffアルゴリズム(貼っただけ"
Really good work about this website was done. Keep trying more – thanks!
Leave a reply