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