ホームページ  >  記事  >  バックエンド開発  >  RMM 単語分割アルゴリズム クラス

RMM 単語分割アルゴリズム クラス

WBOY
WBOYオリジナル
2016-07-25 08:47:54954ブラウズ
RMM 単語分割アルゴリズム クラス
  1. //RMM 単語分割アルゴリズム
  2. class SplitWord{
  3. var $TagDic = Array();
  4. var $RankDic = Array();
  5. var $SourceStr = '';
  6. var $ResultStr = '';
  7. var $ SplitChar = ' '; //Separator
  8. var $SplitLen = 4; // 予約された単語の長さ
  9. var $MaxLen = 7; // ここの値はバイト配列の最大インデックスですvar $MinLen = 3; //最小の中国語文字、ここでの値はバイト配列の最大インデックスです
  10. function SplitWord(){
  11. $this->__construct();
  12. }
  13. function __construct(){
  14. //高度な単語分割、単語分割速度を向上させるために辞書をプリロードします
  15. $dicfile = dirname(__FILE__)."/ppldic.csv"; // 単語を読み取ります辞書
  16. while ($line = fgets($fp,256)){
  17. $ws =explode(' ',$line) // 語彙内の単語を分割します
  18. $this->TagDic[$ws[0 ] ] = $ws[1];
  19. $this->RankDic[strlen($ws[0])][$ws[0]] = $ws[2];
  20. }
  21. fclose($fp); / 辞書ファイルを閉じる
  22. }
  23. // リソースを抽出する
  24. function Clear(){
  25. @fclose($this->QuickDic);
  26. }
  27. // ソース文字列を設定する
  28. function SetSource($str){
  29. $this->SourceStr = $this->UpdateStr($str);
  30. $this->ResultStr = "";
  31. }
  32. //文字列が中国語に存在しないかをチェック
  33. function NotGBK($str) )
  34. {
  35. if($str=="") return "";
  36. if( ord($str[0])>0x80 ) return false;
  37. else return true;
  38. }
  39. //RMM 単語分割アルゴリズム
  40. 関数 SplitRMM ($str=""){
  41. if($str!="") $this->SetSource($str);
  42. if($this->SourceStr=="") return "";
  43. $this ->SourceStr = $this->UpdateStr($this->SourceStr);
  44. $spwords =explode(" ",$this->SourceStr);
  45. $spLen = count($spwords);
  46. $spc = $this->SplitChar;
  47. for($i=($spLen-1);$i>=0;$i--){
  48. if($spwords[$i]=="")続行;
  49. if($this->NotGBK($spwords[$i])){
  50. if(preg_match("/[^0-9.+-]/",$spwords[$i]))
  51. { $this- >ResultStr = $spwords[$i].$spc.$this->ResultStr; }
  52. else
  53. {
  54. $nextword = "";
  55. @$nextword = substr($this->ResultStr, 0,strpos ($this->ResultStr,""));
  56. }
  57. }
  58. else
  59. {
  60. $c = $spwords[$i][0].$spwords[$i][1];
  61. $ n = hexdec (bin2hex($c));
  62. if(strlen($spwords[$i]) <= $this->SplitLen)
  63. {
  64. }
  65. else
  66. {
  67. $this->ResultStr = $ this-> ;RunRMM($spwords[$i]).$spc.$this->ResultStr;
  68. }
  69. }
  70. }
  71. return $this->ResultStr;
  72. }
  73. //すべての中国語の逆一致メソッド文字列を分解する
  74. function RunRMM($str){
  75. $spc = $this->SplitChar;
  76. $spLen = strlen($str);
  77. $rsStr = "";
  78. $okWord = "";
  79. $tmpWord = " " ;
  80. $WordArray = Array();
  81. //辞書の逆引きマッチング
  82. for($i=($spLen-1);$i>=0;){
  83. //最小の単語に到達したとき
  84. if( $i<=$this->MinLen){
  85. if($i==1){
  86. $WordArray[] = substr($str,0,2);
  87. }else
  88. {
  89. $w = substr($ str,0,$this->MinLen+1);
  90. if($this->IsWord($w)){
  91. $WordArray[] = $w;
  92. }else{
  93. $WordArray[] = substr( $str,2,2);
  94. $WordArray[] = substr($str,0,2);
  95. }
  96. }
  97. $i = -1; Break;
  98. }
  99. //最小単語より上の状況を分析する
  100. if($i>=$this->MaxLen) $maxPos = $this->MaxLen;
  101. else $maxPos = $i;
  102. $isMatch = false;
  103. for($j=$maxPos;$j> = 0;$j=$j-2){
  104. $w = substr($str,$i-$j,$j+1);
  105. if($this->IsWord($w)){
  106. $ WordArray [] = $w;
  107. $i = $i-$j-1;
  108. $isMatch = true;
  109. Break;
  110. }
  111. }
  112. }
  113. $rsStr = $this->otherword($WordArray);
  114. return $rsStr;
  115. }
  116. function otherword($WordArray){
  117. $wlen = count($WordArray)-1; //配列の要素数を計算します
  118. $rsStr = "" //変数を初期化します
  119. $spc; = $this->SplitChar;
  120. for($i=$wlen;$i>=0;$i--)
  121. {
  122. $rsStr .= $spc.$WordArray[$i].","; / 配列をカンマで分割します
  123. }
  124. //この段落の単語分割結果を返します
  125. $rsStr = preg_replace("/^".$spc."/",",",$rsStr);
  126. return $rsStr;
  127. }
  128. //特定の単語が辞書に存在するかどうかを判断します
  129. function IsWord($okWord){
  130. $slen = strlen($okWord);
  131. if($slen > $this->MaxLen) return false;
  132. else return isset($this->RankDic[$slen][$okWord]);
  133. }
  134. //文字列の整理(句読点、中国語と英語の混在などの事前処理)
  135. function UpdateStr($str) {
  136. $ spc = $this->SplitChar;
  137. $slen = strlen($str);
  138. if($slen==0) return '';
  139. $okstr = '';
  140. $prechar = 0; // 0-空白 1-英語 2-中国語 3-記号
  141. for($i=0;$i<$slen;$i++){
  142. if(ord($str[$i]) <0x81){
  143. //英語記号の空白
  144. if(ord($str[$i]) < 33){
  145. if($prechar!=0&&$str[$i]!="r"&&$str[$i]!=" n") $okstr .= $spc;
  146. $prechar=0;
  147. continue;
  148. }else if(preg_match("/[^0-9a-zA-Z@.%#:\&_-]/",$ str[$ i])){
  149. if($prechar==0){ $okstr .= $str[$i];}
  150. else{ $okstr .= $spc.$str[$i ]; $ prechar=3;}
  151. }else{
  152. if($prechar==2||$prechar==3)
  153. { $okstr .= $spc.$str[$i];}
  154. else
  155. {
  156. if(preg_match("/@#%:/",$str[$i])){ $okstr .= $str[$i]; }
  157. else { $okstr . = $str [$i]; $prechar=1; }
  158. }
  159. }
  160. }
  161. else{
  162. //前の文字が中国語以外でスペースでない場合は、スペースを追加します
  163. if($prechar!=0 && $prechar! =2) $okstr .= $spc;
  164. //漢字の場合
  165. if(isset($str[$i+1])){
  166. $c = $str[$i].$str[ $i+1 ];
  167. $n = hexdec(bin2hex($c));
  168. if($n<0xA13F && $n > 0xAA40){
  169. if($prechar!=0) $okstr .= $spc .$c;
  170. else $okstr .= $c;
  171. $prechar = 3;
  172. }
  173. else{
  174. $okstr .= $c;
  175. $prechar = 2;
  176. }
  177. $i++;
  178. }
  179. }
  180. }
  181. return $okstr ;
  182. }
  183. }
  184. // Call
  185. $split=new SplitWord();
  186. echo $split->SplitRMM("php search technology");
  187. // ppldic の形式に注意してください.csv 辞書は word+Space+Number+n
コードをコピー


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。