Aquí es una función de resumen se puede utilizar a diferencia de dos matrices. Se implementa el algoritmo LCS:
function computeDiff($from, $to)
{
$diffValues = array();
$diffMask = array();
$dm = array();
$n1 = count($from);
$n2 = count($to);
for ($j = -1; $j < $n2; $j++) $dm[-1][$j] = 0;
for ($i = -1; $i < $n1; $i++) $dm[$i][-1] = 0;
for ($i = 0; $i < $n1; $i++)
{
for ($j = 0; $j < $n2; $j++)
{
if ($from[$i] == $to[$j])
{
$ad = $dm[$i - 1][$j - 1];
$dm[$i][$j] = $ad + 1;
}
else
{
$a1 = $dm[$i - 1][$j];
$a2 = $dm[$i][$j - 1];
$dm[$i][$j] = max($a1, $a2);
}
}
}
$i = $n1 - 1;
$j = $n2 - 1;
while (($i > -1) || ($j > -1))
{
if ($j > -1)
{
if ($dm[$i][$j - 1] == $dm[$i][$j])
{
$diffValues[] = $to[$j];
$diffMask[] = 1;
$j--;
continue;
}
}
if ($i > -1)
{
if ($dm[$i - 1][$j] == $dm[$i][$j])
{
$diffValues[] = $from[$i];
$diffMask[] = -1;
$i--;
continue;
}
}
{
$diffValues[] = $from[$i];
$diffMask[] = 0;
$i--;
$j--;
}
}
$diffValues = array_reverse($diffValues);
$diffMask = array_reverse($diffMask);
return array('values' => $diffValues, 'mask' => $diffMask);
}
Se genera dos matrices:
- valores matriz: una lista de elementos que aparecen en el diff.
- matriz de máscara: contiene números. 0: sin cambios, -1: eliminado, 1: agregado.
Si completa una matriz con caracteres, se puede utilizar para calcular la diferencia en línea. Ahora un solo paso para resaltar las diferencias:
function diffline($line1, $line2)
{
$diff = computeDiff(str_split($line1), str_split($line2));
$diffval = $diff['values'];
$diffmask = $diff['mask'];
$n = count($diffval);
$pmc = 0;
$result = '';
for ($i = 0; $i < $n; $i++)
{
$mc = $diffmask[$i];
if ($mc != $pmc)
{
switch ($pmc)
{
case -1: $result .= '</del>'; break;
case 1: $result .= '</ins>'; break;
}
switch ($mc)
{
case -1: $result .= '<del>'; break;
case 1: $result .= '<ins>'; break;
}
}
$result .= $diffval[$i];
$pmc = $mc;
}
switch ($pmc)
{
case -1: $result .= '</del>'; break;
case 1: $result .= '</ins>'; break;
}
return $result;
}
Ej .:
salida
echo diffline('StackOverflow', 'ServerFault')
Will:
S<del>tackO</del><ins>er</ins>ver<del>f</del><ins>Fau</ins>l<del>ow</del><ins>t</ins>
S Tacko erver f Faul flujo t
Notas adicionales:
- La matriz de diferencias requiere (m + 1) * (n + 1) elementos. Por lo tanto, puede ejecutar errores sin memoria si intenta diferir secuencias largas. En este caso, difiera trozos más grandes (por ejemplo, líneas) primero, luego difunda su contenido en un segundo pase.
- El algoritmo se puede mejorar si recorta los elementos coincidentes desde el principio y el final, luego ejecuta el algoritmo solo en el medio diferente. Un latter (more bloated) version contiene estas modificaciones también.
el enlace ya no funciona. ¿Hay alguna otra solución ahora en 2011? ;-) es posible obtener un resultado como este http://tortoisesvn.tigris.org/images/TMerge2Diff.png –
El sitio se ha ido, pero archive.org tiene una copia del sitio: http: //web.archive .org/web/20080506155528/http: //software.zuavra.net/inline-diff/ –
Lástima que requiera PEAR. PEAR-dependencia chupa. – Rudie