欢迎光临
我们一直在努力

PHP改进计算字符串相似度的函数similar_text()、levenshtein()

PHP 原生的similar_text()函数、levenshtein()函数对中文汉字支持不好,我自己写了一个,测试使用正常,推荐给大家,如果有什么问题,请留言

similar_text()中文汉字版,代码如下:

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

最长公共子序列LCS(),代码如下:

  1. <?php  
  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.            $dp = array();  
  8.            for ($i = 0; $i <= $len$i++) {  
  9.              $dp[$i] = array();  
  10.              $dp[$i][0] = 0;  
  11.              $dp[0][$i] = 0;  
  12.            }  
  13.            for ($i = 1; $i <= $len_1$i++) {  
  14.              for ($j = 1; $j <= $len_2$j++) {  
  15.                if ($str_1[$i – 1] == $str_2[$j – 1]) {  
  16.                  $dp[$i][$j] = $dp[$i – 1][$j – 1] + 1;  
  17.                } else {  
  18.                  $dp[$i][$j] = $dp[$i – 1][$j] > $dp[$i][$j – 1] ? $dp[$i – 1][$j] : $dp[$i][$j – 1];  
  19.                }  
  20.              }  
  21.            }  
  22.            return $dp[$len_1][$len_2];  
  23.          }  
  24.          //拆分字符串  
  25.          function mbStringToArray($string$encoding = 'UTF-8') {  
  26.            $arrayResult = array();  
  27.            while ($iLen = mb_strlen($string$encoding)) {  
  28.              array_push($arrayResult, mb_substr($string, 0, 1, $encoding));  
  29.              $string = mb_substr($string, 1, $iLen$encoding);  
  30.            }  
  31.            return $arrayResult;  
  32.          }  
  33.          //最长公共子序列中文版  
  34.          function LCS_cn($str1$str2$encoding = 'UTF-8') {  
  35.            $mb_len1 = mb_strlen($str1$encoding);  
  36.            $mb_len2 = mb_strlen($str2$encoding);  
  37.            $mb_str1 = mbStringToArray($str1$encoding);  
  38.            $mb_str2 = mbStringToArray($str2$encoding);  
  39.            $len = $mb_len1 > $mb_len2 ? $mb_len1 : $mb_len2;  
  40.            $dp = array();  
  41.            for ($i = 0; $i <= $len$i++) {  
  42.              $dp[$i] = array();  
  43.              $dp[$i][0] = 0;  
  44.              $dp[0][$i] = 0;  
  45.            }  
  46.            for ($i = 1; $i <= $mb_len1$i++) {  
  47.              for ($j = 1; $j <= $mb_len2$j++) {  
  48.                if ($mb_str1[$i – 1] == $mb_str2[$j – 1]) {  
  49.                  $dp[$i][$j] = $dp[$i – 1][$j – 1] + 1;  
  50.                } else {  
  51.                  $dp[$i][$j] = $dp[$i – 1][$j] > $dp[$i][$j – 1] ? $dp[$i – 1][$j] : $dp[$i][$j – 1];  
  52.                }  
  53.              }  
  54.            }  
  55.            return $dp[$mb_len1][$mb_len2];  
  56.          } 

赞(0) 本模板价: 打赏
未经允许不得转载:站长分享圈 » PHP改进计算字符串相似度的函数similar_text()、levenshtein()