array_fill(-1, $n - $m + $k + 3, -2)]; for ($q = 0, $max = $k - 1; $q <= $max; ++$q) { $L[$q][-$q - 1] = $L[$q][-$q - 2] = $q - 1; } for ($q = 0; $q <= $k; ++$q) { for ($d = -$q, $max = $n - $m + $k - $q; $d <= $max; ++$d) { $l = min( max( $L[$q - 1][$d - 1], $L[$q - 1][$d ] + 1, $L[$q - 1][$d + 1] + 1 ), $m - 1 ); $a = substr($x, $l + 1, $m - $l); $b = substr($y, $l + 1 + $d, $n - $l - $d); $L[$q][$d] = $l + static::lcp($a, $b); if ($L[$q][$d] == $m - 1 || $d + $L[$q][$d] == $n - 1) { $j = $m + $d; $i = max(0, $j - $m); $offset[$q][] = ['i' => $i, 'j' => $j, 'l' => $j - $i]; } } } return empty($offset) ? $offset : $offset[$k]; } /** * Length of the longest common prefixes. * * @param string $x Word. * @param string $y Word. * @return int */ public static function lcp($x, $y) { $max = min(strlen($x), strlen($y)); $i = 0; while ($i < $max && $x[$i] == $y[$i]) { ++$i; } return $i; } }