annotate vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents 7a779792577d
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /*
Chris@12 3 * This file is part of sebastian/diff.
Chris@0 4 *
Chris@0 5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
Chris@0 6 *
Chris@0 7 * For the full copyright and license information, please view the LICENSE
Chris@0 8 * file that was distributed with this source code.
Chris@0 9 */
Chris@0 10
Chris@0 11 namespace SebastianBergmann\Diff\LCS;
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Memory-efficient implementation of longest common subsequence calculation.
Chris@0 15 */
Chris@0 16 class MemoryEfficientImplementation implements LongestCommonSubsequence
Chris@0 17 {
Chris@0 18 /**
Chris@0 19 * Calculates the longest common subsequence of two arrays.
Chris@0 20 *
Chris@0 21 * @param array $from
Chris@0 22 * @param array $to
Chris@0 23 *
Chris@0 24 * @return array
Chris@0 25 */
Chris@0 26 public function calculate(array $from, array $to)
Chris@0 27 {
Chris@12 28 $cFrom = \count($from);
Chris@12 29 $cTo = \count($to);
Chris@0 30
Chris@12 31 if ($cFrom === 0) {
Chris@0 32 return array();
Chris@12 33 }
Chris@12 34
Chris@12 35 if ($cFrom === 1) {
Chris@12 36 if (\in_array($from[0], $to, true)) {
Chris@0 37 return array($from[0]);
Chris@0 38 }
Chris@0 39
Chris@12 40 return array();
Chris@12 41 }
Chris@0 42
Chris@12 43 $i = (int) ($cFrom / 2);
Chris@12 44 $fromStart = \array_slice($from, 0, $i);
Chris@12 45 $fromEnd = \array_slice($from, $i);
Chris@12 46 $llB = $this->length($fromStart, $to);
Chris@12 47 $llE = $this->length(\array_reverse($fromEnd), \array_reverse($to));
Chris@12 48 $jMax = 0;
Chris@12 49 $max = 0;
Chris@12 50
Chris@12 51 for ($j = 0; $j <= $cTo; $j++) {
Chris@12 52 $m = $llB[$j] + $llE[$cTo - $j];
Chris@12 53
Chris@12 54 if ($m >= $max) {
Chris@12 55 $max = $m;
Chris@12 56 $jMax = $j;
Chris@12 57 }
Chris@0 58 }
Chris@12 59
Chris@12 60 $toStart = \array_slice($to, 0, $jMax);
Chris@12 61 $toEnd = \array_slice($to, $jMax);
Chris@12 62
Chris@12 63 return \array_merge(
Chris@12 64 $this->calculate($fromStart, $toStart),
Chris@12 65 $this->calculate($fromEnd, $toEnd)
Chris@12 66 );
Chris@0 67 }
Chris@0 68
Chris@0 69 /**
Chris@0 70 * @param array $from
Chris@0 71 * @param array $to
Chris@0 72 *
Chris@0 73 * @return array
Chris@0 74 */
Chris@0 75 private function length(array $from, array $to)
Chris@0 76 {
Chris@12 77 $current = \array_fill(0, \count($to) + 1, 0);
Chris@12 78 $cFrom = \count($from);
Chris@12 79 $cTo = \count($to);
Chris@0 80
Chris@0 81 for ($i = 0; $i < $cFrom; $i++) {
Chris@0 82 $prev = $current;
Chris@0 83
Chris@0 84 for ($j = 0; $j < $cTo; $j++) {
Chris@12 85 if ($from[$i] === $to[$j]) {
Chris@0 86 $current[$j + 1] = $prev[$j] + 1;
Chris@0 87 } else {
Chris@12 88 $current[$j + 1] = \max($current[$j], $prev[$j + 1]);
Chris@0 89 }
Chris@0 90 }
Chris@0 91 }
Chris@0 92
Chris@0 93 return $current;
Chris@0 94 }
Chris@0 95 }