PHP similar_text()、levenshtein()、lcs()支持中文汉字版,


PHP 原生的similar_text()函数、levenshtein()函数对中文汉字支持不好,我自己写了一个


similar_text()中文汉字版

 1      2     //拆分字符串  
 3     function split_str($str) {  
 4       preg_match_all("/./u", $str, $arr);  
 5       return $arr[0];  
 6     }  
 7       
 8     //相似度检测  
 9     function similar_text_cn($str1, $str2) {  
10       $arr_1 = array_unique(split_str($str1));  
11       $arr_2 = array_unique(split_str($str2));  
12       $similarity = count($arr_2) - count(array_diff($arr_2, $arr_1));  
13         
14       return $similarity;  
15     }  
登录后复制

levenshtein()中文汉字版

 1      2     //拆分字符串  
 3     function mbStringToArray($string, $encoding = 'UTF-8') {  
 4         $arrayResult = array();  
 5       
 6         while ($iLen = mb_strlen($string, $encoding)) {  
 7             array_push($arrayResult, mb_substr($string, 0, 1, $encoding));  
 8             $string = mb_substr($string, 1, $iLen, $encoding);  
 9         }  
10       
11         return $arrayResult;  
12     }  
13       
14     //编辑距离  
15     function levenshtein_cn($str1, $str2, $costReplace = 1, $encoding = 'UTF-8') {  
16         $count_same_letter = 0;  
17         $d = array();  
18       
19         $mb_len1 = mb_strlen($str1, $encoding);  
20         $mb_len2 = mb_strlen($str2, $encoding);  
21       
22         $mb_str1 = mbStringToArray($str1, $encoding);  
23         $mb_str2 = mbStringToArray($str2, $encoding);  
24       
25         for ($i1 = 0; $i1 ; $i1++) {  
26             $d[$i1] = array();  
27             $d[$i1][0] = $i1;  
28         }  
29       
30         for ($i2 = 0; $i2 ; $i2++) {  
31             $d[0][$i2] = $i2;  
32         }  
33       
34         for ($i1 = 1; $i1 ; $i1++) {  
35             for ($i2 = 1; $i2 ; $i2++) {  
36                 // $cost = ($str1[$i1 - 1] == $str2[$i2 - 1]) ? 0 : 1;  
37                 if ($mb_str1[$i1 - 1] === $mb_str2[$i2 - 1]) {  
38                     $cost = 0;  
39                     $count_same_letter++;  
40                 } else {  
41                     $cost = $costReplace; //替换  
42                 }  
43       
44                 $d[$i1][$i2] = min($d[$i1 - 1][$i2] + 1, //插入  
45                 $d[$i1][$i2 - 1] + 1, //删除  
46                 $d[$i1 - 1][$i2 - 1] + $cost);  
47             }  
48         }  
49       
50         return $d[$mb_len1][$mb_len2];  
51         //return array('distance' => $d[$mb_len1][$mb_len2], 'count_same_letter' => $count_same_letter);  
52     }  
登录后复制

最长公共子序列LCS()

 1          2         //最长公共子序列英文版  
 3         function LCS_en($str_1, $str_2) {  
 4           $len_1 = strlen($str_1);  
 5           $len_2 = strlen($str_2);  
 6           $len = $len_1 > $len_2 ? $len_1 : $len_2;  
 7           
 8           $dp = array();  
 9           for ($i = 0; $i ; $i++) {  
10             $dp[$i] = array();  
11             $dp[$i][0] = 0;  
12             $dp[0][$i] = 0;  
13           }  
14           
15           for ($i = 1; $i ; $i++) {  
16             for ($j = 1; $j ; $j++) {  
17               if ($str_1[$i - 1] == $str_2[$j - 1]) {  
18                 $dp[$i][$j] = $dp[$i - 1][$j - 1] + 1;  
19               } else {  
20                 $dp[$i][$j] = $dp[$i - 1][$j] > $dp[$i][$j - 1] ? $dp[$i - 1][$j] : $dp[$i][$j - 1];  
21               }  
22             }  
23           }  
24           
25           return $dp[$len_1][$len_2];  
26         }  
27           
28         //拆分字符串  
29         function mbStringToArray($string, $encoding = 'UTF-8') {  
30           $arrayResult = array();  
31           
32           while ($iLen = mb_strlen($string, $encoding)) {  
33             array_push($arrayResult, mb_substr($string, 0, 1, $encoding));  
34             $string = mb_substr($string, 1, $iLen, $encoding);  
35           }  
36           
37           return $arrayResult;  
38         }  
39           
40         //最长公共子序列中文版  
41         function LCS_cn($str1, $str2, $encoding = 'UTF-8') {  
42           $mb_len1 = mb_strlen($str1, $encoding);  
43           $mb_len2 = mb_strlen($str2, $encoding);  
44           
45           $mb_str1 = mbStringToArray($str1, $encoding);  
46           $mb_str2 = mbStringToArray($str2, $encoding);  
47           
48           $len = $mb_len1 > $mb_len2 ? $mb_len1 : $mb_len2;  
49           
50           $dp = array();  
51           for ($i = 0; $i ; $i++) {  
52             $dp[$i] = array();  
53             $dp[$i][0] = 0;  
54             $dp[0][$i] = 0;  
55           }  
56           
57           for ($i = 1; $i ; $i++) {  
58             for ($j = 1; $j ; $j++) {  
59               if ($mb_str1[$i - 1] == $mb_str2[$j - 1]) {  
60                 $dp[$i][$j] = $dp[$i - 1][$j - 1] + 1;  
61               } else {  
62                 $dp[$i][$j] = $dp[$i - 1][$j] > $dp[$i][$j - 1] ? $dp[$i - 1][$j] : $dp[$i][$j - 1];  
63               }  
64             }  
65           }  
66           
67           return $dp[$mb_len1][$mb_len2];  
68         } 
登录后复制



09-18 07:00