annotate vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents 5311817fb629
children
rev   line source
Chris@2 1 <?php declare(strict_types=1);
Chris@2 2 /*
Chris@2 3 * This file is part of sebastian/diff.
Chris@2 4 *
Chris@2 5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
Chris@2 6 *
Chris@2 7 * For the full copyright and license information, please view the LICENSE
Chris@2 8 * file that was distributed with this source code.
Chris@2 9 */
Chris@2 10
Chris@2 11 namespace SebastianBergmann\Diff;
Chris@2 12
Chris@2 13 final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
Chris@2 14 {
Chris@2 15 /**
Chris@2 16 * {@inheritdoc}
Chris@2 17 */
Chris@2 18 public function calculate(array $from, array $to): array
Chris@2 19 {
Chris@2 20 $cFrom = \count($from);
Chris@2 21 $cTo = \count($to);
Chris@2 22
Chris@2 23 if ($cFrom === 0) {
Chris@2 24 return [];
Chris@2 25 }
Chris@2 26
Chris@2 27 if ($cFrom === 1) {
Chris@2 28 if (\in_array($from[0], $to, true)) {
Chris@2 29 return [$from[0]];
Chris@2 30 }
Chris@2 31
Chris@2 32 return [];
Chris@2 33 }
Chris@2 34
Chris@2 35 $i = (int) ($cFrom / 2);
Chris@2 36 $fromStart = \array_slice($from, 0, $i);
Chris@2 37 $fromEnd = \array_slice($from, $i);
Chris@2 38 $llB = $this->length($fromStart, $to);
Chris@2 39 $llE = $this->length(\array_reverse($fromEnd), \array_reverse($to));
Chris@2 40 $jMax = 0;
Chris@2 41 $max = 0;
Chris@2 42
Chris@2 43 for ($j = 0; $j <= $cTo; $j++) {
Chris@2 44 $m = $llB[$j] + $llE[$cTo - $j];
Chris@2 45
Chris@2 46 if ($m >= $max) {
Chris@2 47 $max = $m;
Chris@2 48 $jMax = $j;
Chris@2 49 }
Chris@2 50 }
Chris@2 51
Chris@2 52 $toStart = \array_slice($to, 0, $jMax);
Chris@2 53 $toEnd = \array_slice($to, $jMax);
Chris@2 54
Chris@2 55 return \array_merge(
Chris@2 56 $this->calculate($fromStart, $toStart),
Chris@2 57 $this->calculate($fromEnd, $toEnd)
Chris@2 58 );
Chris@2 59 }
Chris@2 60
Chris@2 61 private function length(array $from, array $to): array
Chris@2 62 {
Chris@2 63 $current = \array_fill(0, \count($to) + 1, 0);
Chris@2 64 $cFrom = \count($from);
Chris@2 65 $cTo = \count($to);
Chris@2 66
Chris@2 67 for ($i = 0; $i < $cFrom; $i++) {
Chris@2 68 $prev = $current;
Chris@2 69
Chris@2 70 for ($j = 0; $j < $cTo; $j++) {
Chris@2 71 if ($from[$i] === $to[$j]) {
Chris@2 72 $current[$j + 1] = $prev[$j] + 1;
Chris@2 73 } else {
Chris@2 74 $current[$j + 1] = \max($current[$j], $prev[$j + 1]);
Chris@2 75 }
Chris@2 76 }
Chris@2 77 }
Chris@2 78
Chris@2 79 return $current;
Chris@2 80 }
Chris@2 81 }