已有40人关注
致明日科技
发表在PHP图书答疑 2010-09-07
是否精华
版块置顶:
工作人员你们好,我是你们的读者,已经买了你们两本书籍,我现在研究《php典型模块技术大全修订版》
搜索引擎模块中分词类的问题,你们的解决让我感觉不到你们的承诺,
做为你们的读者,有问题,难道你们不愿意帮忙解决吗?
每当提问一次,就要等一个星期左右的时间才能看到答复,而且还不能解决问题,
我期盼的心情,有些愤怒
大家都是研究技术的,你们的态度好些行不行呢?
我现在真的很失望,我想很多读者都有类似的心情吧,
你们难道感觉不到读者的心声吗?


class SplitWord{
var $TagDic = Array();
var $RankDic = Array();
var $SourceStr = '';
var $ResultStr = '';
var $SplitChar = ' '; //分隔符
var $SplitLen = 4;  //保留词长度
var $MaxLen = 7;  //词典最大中文字,这里的数值为字节数组的最大索引
var $MinLen = 3;  //最小中文字,这里的数值为字节数组的最大索引

  function SplitWord(){
   $this->__construct();
  }

  function __construct(){
   //高级分词,预先载入词典以提分词高速度
   $dicfile = dirname(__FILE__)."/ppldic.csv";
   $fp = fopen($dicfile,'r'); //读取词库中的词 只读方式
   while($line = fgets($fp,256)){     //为什么是256呢?
     $ws = explode(' ',$line); //对词库中的词进行拆分 保存在数组中
     $this->TagDic[$ws[0]] = $ws[1];//不懂是什么意思了
     $this->RankDic[strlen($ws[0])][$ws[0]] = $ws[2];//不懂啊
   }
   fclose($fp); //关闭词库文件
  }

  //析放资源
 function Clear(){
   @fclose($this->QuickDic);
  }

  //设置源字符串
  function SetSource($str){
   $this->SourceStr = $this->UpdateStr($str);
   $this->ResultStr = "";
  }

  //检查字符串是否不存在中文 不存在返回true;
  function NotGBK($str)
  {
    if($str=="") return "";
   if( ord($str[0])>0x80 ) return false;
   else return true;
  }

  //RMM分词算法
  function SplitRMM($str=""){
   if($str!="") $this->SetSource($str);
   if($this->SourceStr=="") return "";
   $this->SourceStr = $this->UpdateStr($this->SourceStr);
   $spwords = explode(" ",$this->SourceStr);
   $spLen = count($spwords);
   $spc = $this->SplitChar;
   for($i=($spLen-1);$i>=0;$i--){
   if($spwords[$i]=="") continue;
   if($this->NotGBK($spwords[$i])){
   if(ereg("[^0-9\.\+\-]",$spwords[$i]))
   { $this->ResultStr = $spwords[$i].$spc.$this->ResultStr; }
   else
   {
   $nextword = "";
   @$nextword = substr($this->ResultStr,0,strpos($this->ResultStr,""));
   }
   }
   else
   {
     $c = $spwords[$i][0].$spwords[$i][1];
     $n = hexdec(bin2hex($c));  //hexdec()函数是把十六进制转换成十进制 bin2hex()函数把2进制参数转换成16进制
      if(strlen($spwords[$i]) <= $this->SplitLen)
      {
      }
      else
      {
      $this->ResultStr = $this->RunRMM($spwords[$i]).$spc.$this->ResultStr;
      }
     }
   }
   return $this->ResultStr;
  }
  //对全中文字符串进行逆向匹配方式分解
  function RunRMM($str){
   $spc = $this->SplitChar; //分隔符
   $spLen = strlen($str); //用户输入字符串长度
   $rsStr = "";
   $okWord = "";
   $tmpWord = "";
   $WordArray = Array();
   //逆向字典匹配
   for($i=($spLen-1);$i>=0;){
   //当i达到最小可能词的时候
   if($i<=$this->MinLen){
   if($i==1){
     $WordArray[] = substr($str,0,2);
     }else
   {
      $w = substr($str,0,$this->MinLen+1);
      if($this->IsWord($w)){
       $WordArray[] = $w;
      }else{
      $WordArray[] = substr($str,2,2);
      $WordArray[] = substr($str,0,2);
      }
     }
   $i = -1; break;
   }
   //分析在最小词以上时的情况
   if($i>=$this->MaxLen) $maxPos = $this->MaxLen;
   else $maxPos = $i;
   $isMatch = false;
   for($j=$maxPos;$j>=0;$j=$j-2){
    $w = substr($str,$i-$j,$j+1);
    if($this->IsWord($w)){
     $WordArray[] = $w;
     $i = $i-$j-1;
     $isMatch = true;
     break;
    }
   }
   }
   $rsStr = $this->otherword($WordArray);
   return $rsStr;
  }

function otherword($WordArray){
   $wlen = count($WordArray)-1; //计算数组的元素个数
   $rsStr = ""; //初始化变量
   $spc = $this->SplitChar;
   for($i=$wlen;$i>=0;$i--)
   {
$rsStr .= $spc.$WordArray[$i]."、"; //将数组为顿号进行拆分
   }
   //返回本段分词结果
$rsStr = preg_replace("/^".$spc."/","、",$rsStr);
   return $rsStr;
  }

  //判断词典里是否存在某个词
  function IsWord($okWord){
   $slen = strlen($okWord);
   if($slen > $this->MaxLen) return false;
   else return isset($this->RankDic[$slen][$okWord]);
  }

  //整理字符串(对标点符号,中英文混排等初步处理)
  function UpdateStr($str){
   $spc = $this->SplitChar;
    $slen = strlen($str);
    if($slen==0) return '';
    $okstr = '';
    $prechar = 0; // 0-空白 1-英文 2-中文 3-符号
    for($i=0;$i<$slen;$i++){
      if(ord($str[$i]) < 0x81){
        //英文的空白符号
        if(ord($str[$i]) < 33){
          if($prechar!=0&&$str[$i]!="\r"&&$str[$i]!="\n") $okstr .= $spc;
          $prechar=0;
          continue;
        }else if(ereg("[^0-9a-zA-Z@\.%#:/\\&_-]",$str[$i])){
          if($prechar==0){ $okstr .= $str[$i]; $prechar=3;}
          else{ $okstr .= $spc.$str[$i]; $prechar=3;}
        }else{
         if($prechar==2||$prechar==3)
         { $okstr .= $spc.$str[$i]; $prechar=1;}
         else
         {
           if(ereg("@#%:",$str[$i])){ $okstr .= $str[$i]; $prechar=3; }
           else { $okstr .= $str[$i]; $prechar=1; }
         }
        }
      }
      else{
        //如果上一个字符为非中文和非空格,则加一个空格
        if($prechar!=0 && $prechar!=2) $okstr .= $spc;
        //如果中文字符
        if(isset($str[$i+1])){
          $c = $str[$i].$str[$i+1];

          $n = hexdec(bin2hex($c));
          if($n<0xA13F && $n > 0xAA40){
             if($prechar!=0) $okstr .= $spc.$c;
             else $okstr .= $c;
             $prechar = 3;
            }
          else{
            $okstr .= $c;
            $prechar = 2;
          }
          $i++;
        }
      }
    }
    return $okstr;
  }
}
?>

上次提问,我不懂的地方,你们的一个工作人员说让我删掉,可是我删掉之后根本无法查询了,我问为什么要删掉,能不能解释一下,也没有人回答,你们的态度,让读者很上火的,东北人都是很爽快的,如果这样的事情发生在你们身上,我想你们的火会更大,希望帮忙解决一下搜索引擎分此类的问题啊,我注释的地方是我不懂的地方,希望你们帮帮忙,谢谢了
言语有过分之处还望见谅,急切心情,希望你们能理解
分享到:
精彩评论 1
346827366
学分:0 LV1
2010-09-09
沙发
function __construct(){
//高级分词,预先载入词典以提分词高速度
$dicfile = dirname(__FILE__)."/ppldic.csv";
$fp = fopen($dicfile,'r'); //读取词库中的词 只读方式
while($line = fgets($fp,256)){                       //这个值是自己设置的,也可以是1024,

其目的是只要能读取完文件中的一行数据就行?

$ws = explode(' ',$line); //对词库中的词进行拆分 保存在数组中
$this->TagDic[$ws[0]] = $ws[1];      //将读取的分词数据进行重组存储到数组中,以ppldic.csv文件中的词组为关联索引,将词组的排序值作为元素值;

$this->RankDic[strlen($ws[0])][$ws[0]] = $ws[2];//将读取的分词数据进行重组存储到数组中,以ppldic.csv文件中的词组为关联索引,将字符n作为元素值;

}
fclose($fp); //关闭词库文件
}



你可以在程序的根目录下定义一个example.php文件,其内容如下:
$TagDic = Array();
$RankDic = Array();
$dicfile = dirname(__FILE__)."/ppldic.csv";
$fp = fopen($dicfile,'r'); //读取词库中的词 只读方式
while($line = fgets($fp,256)){                       //这个值是自己设置的,也可以是1024,
    $ws = explode(' ',$line); //对词库中的词进行拆分 保存在数组中
    $TagDic[$ws[0]] = $ws[1];      //将读取的分词数据进行重组存储到数组中
    $RankDic[strlen($ws[0])][$ws[0]] = $ws[2];//将读取的分词数据进行
print_r($TagDic);
print_r($RankDic);

}
fclose($fp); //关闭词库文件

运行这个文件,理解这段代码的功能
首页上一页 1 下一页尾页 1 条记录 1/1页
手机同步功能介绍
友情提示:以下图书配套资源能够实现手机同步功能
明日微信公众号
明日之星 明日之星编程特训营
客服热线(每日9:00-17:00)
400 675 1066
mingrisoft@mingrisoft.com
吉林省明日科技有限公司Copyright ©2007-2022,mingrisoft.com, All Rights Reserved长春市北湖科技开发区盛北大街3333号长春北湖科技园项目一期A10号楼四、五层
吉ICP备10002740号-2吉公网安备22010202000132经营性网站备案信息 营业执照