Passed
Pull Request — master (#10)
by Akpé Aurelle Emmanuel Moïse
02:03
created

levenshteinDistance::levenshtein()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 21
rs 9.7998
c 0
b 0
f 0
cc 4
nc 3
nop 2
1
<?php
2
3
/**
4
*
5
* @Name : similar-text
6
* @Programmer : Akpé Aurelle Emmanuel Moïse Zinsou
7
* @Date : 2019-04-01
8
* @Released under : https://github.com/manuwhat/similar-text/blob/master/LICENSE
9
* @Repository : https://github.com/manuwhat/similar
10
*
11
**/
12
13
14
namespace EZAMA{
15
    class levenshteinDistance extends distance
16
    {
17
        public static function levenshtein($a, $b)
18
        {
19
            if (!is_string($a)||!is_string($b)) {
20
                return false;
21
            }
22
            
23
            
24
            static $distance=0;
25
            static $previous=array();
26
            if (array($a,$b)===$previous) {
27
                return $distance;
28
            }
29
            $previous=array($a,$b);
30
            $a=self::split($a);
31
            $b=self::split($b);
32
            $ca = count((array)$a);
33
            $cb = count((array)$b);
34
            $dis = range(0, $cb);
35
            self::BuildLevenshteinCostMatrix($a, $b, $ca, $cb, $dis);
36
37
            return $distance=$dis[$cb];
38
        }
39
        
40
        
41
        public static function levenshteinDamerau($a, $b)
42
        {
43
            if (!is_string($a)||!is_string($b)) {
44
                return false;
45
            }
46
              
47
            static $distance=0;
48
            static $previous=array();
49
            if (array($a,$b)===$previous) {
50
                return $distance;
51
            }
52
            $previous=array($a,$b);
53
            $a=self::split($a);
54
            $b=self::split($b);
55
            $ca = count((array)$a);
56
            $cb = count((array)$b);
57
            $dis = range(0, $cb);
58
            self::BuildLevenshteinCostMatrix($a, $b, $ca, $cb, $dis, true);
59
        
60
            return $distance=$dis[$cb];
61
        }
62
        
63
        private static function BuildLevenshteinCostMatrix($a, $b, $ca, $cb, &$dis, $damerau=false)
64
        {
65
            $dis_new=array();
66
            for ($x=1;$x<=$ca;$x++) {
67
                $dis_new[0]=$x;
68
                for ($y=1;$y<=$cb;$y++) {
69
                    self::costMatrix($a, $b, $dis_new, $dis, $damerau, $x, $y);
70
                }
71
                $dis = $dis_new;
72
            }
73
        }
74
        
75
        private static function costMatrix(&$a, &$b, &$dis_new, &$dis, $damerau, $x, $y)
76
        {
77
            $c = ($a[$x-1] == $b[$y-1])?0:1;
78
            $dis_new[$y] = min($dis[$y]+1, $dis_new[$y-1]+1, $dis[$y-1]+$c);
79
            if ($damerau) {
80
                if ($x > 1 && $y > 1 && $a[$x-1] == $b[$y-2] && $a[$x-2] == $b[$y-1]) {
81
                    $dis_new[$y]= min($dis_new[$y-1], $dis[$y-3] + $c) ;
82
                }
83
            }
84
        }
85
    }
86
}
87