Test Failed
Pull Request — master (#49)
by Josh
03:22
created

LcsService::compileMatches()   B

Complexity

Conditions 10
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
cc 10
eloc 8
c 2
b 0
f 2
nc 4
nop 6
dl 0
loc 11
rs 7.2765

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Caxy\HtmlDiff;
4
5
use Caxy\HtmlDiff\Strategy\EqualMatchStrategy;
6
use Caxy\HtmlDiff\Strategy\MatchStrategyInterface;
7
8
class LcsService
9
{
10
    /**
11
     * @var MatchStrategyInterface
12
     */
13
    protected $matchStrategy;
14
15
    /**
16
     * LcsService constructor.
17
     *
18
     * @param MatchStrategyInterface $matchStrategy
0 ignored issues
show
Documentation introduced by
Should the type for parameter $matchStrategy not be null|MatchStrategyInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
19
     */
20
    public function __construct(MatchStrategyInterface $matchStrategy = null)
21
    {
22
        if (null === $matchStrategy) {
23
            $matchStrategy = new EqualMatchStrategy();
24
        }
25
26
        $this->matchStrategy = $matchStrategy;
27
    }
28
29
    /**
30
     * @param array $a
31
     * @param array $b
32
     *
33
     * @return array
34
     */
35
    public function longestCommonSubsequence(array $a, array $b)
36
    {
37
        $c = array();
38
39
        $m = count($a);
40
        $n = count($b);
41
42
        for ($i = 0; $i <= $m; $i++) {
43
            $c[$i][0] = 0;
44
        }
45
46
        for ($j = 0; $j <= $n; $j++) {
47
            $c[0][$j] = 0;
48
        }
49
50
        for ($i = 1; $i <= $m; $i++) {
51
            for ($j = 1; $j <= $n; $j++) {
52
                if ($this->matchStrategy->isMatch($a[$i - 1], $b[$j - 1])) {
53
                    $c[$i][$j] = 1 + (isset($c[$i - 1][$j - 1]) ? $c[$i - 1][$j - 1] : 0);
54
                } else {
55
                    $c[$i][$j] = max(
56
                        isset($c[$i][$j - 1]) ? $c[$i][$j - 1] : 0,
57
                        isset($c[$i - 1][$j]) ? $c[$i - 1][$j] : 0
58
                    );
59
                }
60
            }
61
        }
62
63
        $lcs = array_pad([], $m + 1, 0);
64
        $this->compileMatches($c, $a, $b, $m, $n, $lcs);
65
66
        return $lcs;
67
    }
68
69
    /**
70
     * @param $c
71
     * @param $a
72
     * @param $b
73
     * @param $i
74
     * @param $j
75
     * @param $matches
76
     */
77
    protected function compileMatches($c, $a, $b, $i, $j, &$matches)
78
    {
79
        if ($i > 0 && $j > 0 && $this->matchStrategy->isMatch($a[$i - 1], $b[$j - 1])) {
80
            $this->compileMatches($c, $a, $b, $i - 1, $j - 1, $matches);
81
            $matches[$i] = $j;
82
        } elseif ($j > 0 && ($i === 0 || $c[$i][$j - 1] >= $c[$i - 1][$j])) {
83
            $this->compileMatches($c, $a, $b, $i, $j - 1, $matches);
84
        } elseif ($i > 0 && ($j === 0 || $c[$i][$j - 1] < $c[$i - 1][$j])) {
85
            $this->compileMatches($c, $a, $b, $i - 1, $j, $matches);
86
        }
87
    }
88
}
89