PHP 搜索分词实现代码

<?php 
/**
 * @author: xiaojiang 2014-01-08
 * php 建立分词树
 * */
class Tree{

    public $w = '';
    public $subT = array();
    public $isEnd = false;
    
    public function __construct($w= '' , $isEnd = false){
        if(!empty($w)){
            $this->w = $w;
            $this->isEnd = $isEnd;
        }
    }
    public function insert( $str ){
    
        $len = strlen($str);
        if(!$len) return ;
        $scope = $this;
        for( $i = 0; $i< $len; $i++ ){
            //判断汉字
            $cStr = $str[$i];
            if( ord( $cStr ) > 127 ){
                $cStr = substr($str, $i, 3);
                $i += 2;
            }
            $scope = $scope->insertNode( $cStr );
        }
        $scope->isEnd = true;
    }
    
    private function &insertNode(  $w ){
        $t = $this->hasTree( $w );
        if( !$t ){
            $t =  new Tree( $w );
            array_push($this->subT, $t );
        }
        return $t;
    }
    
    public function &hasTree($w){
        foreach ($this->subT as $t){
            if($t->w == $w)
                return $t;
        }
        return false;
    }

}


class myStr{
    
    private $str = '';
    private $arr = array();
    private $len = 0;
    public function __construct( $str){
        $this->str = $str;
        $len = strlen($str);
        for ($i = 0; $i < $len; $i++ ){
            $cStr = $str[$i];
            if(ord($cStr) > 127){
                $cStr = substr($str, $i , 3);
                $i += 2;
            }
            array_push($this->arr, $cStr);
        }
        $this->len = count($this->arr);
    }
    
    public function getIndex( $idx ){
        return $this->arr[$idx];
    }
    
    public function getLength(){
        return $this->len;
    }
}

$tIns = new Tree();
$tIns->insert('中华');
$tIns->insert('人民');
$tIns->insert('共和国');
$tIns->insert('baidu');

$strIns = new myStr("cc中华的人民共和国和中国啊啊www.baidua.com");

for ($i = 0; $i < $strIns->getLength(); $i++ ){
    
    $j = $i;
    $curW = $strIns->getIndex($i);
    $stIns = $tIns->hasTree( $curW );
    if(!$stIns) continue;
    
    $sw = '';
    while ( $stIns ){
        $sw .= $stIns->w; 
        $_isEnd = $stIns->isEnd;
        $stIns = $stIns->hasTree( $strIns->getIndex( ++$j ) );
        if( !$stIns && !$_isEnd)
            $sw = '';
    }
    if($sw)
        echo $sw."<br>";
}


?>

 输出:

中华
人民
共和国
baidu
PHP中文分词代码使用居于unicode的词库,使用反向匹配模式分词,理论上兼容编码更广泛,并且对utf-8编码尤为方便。由于PhpanAlysis是无组件的系统,因此速度会比有组件的稍慢,不过在大量分词中,由于边分词边完成词库载入,因此内容越多,反而会觉得速度越快,这是正常现象,对于支持PHP-APC的服务器,本程序支持对词典进行缓存,这样做之后理论的速度并不慢于那些带组件的分词程序了。 分词系统是基于字符串匹配的分词方法 ,这种方法又叫做机械分词方法,它是按照一定的策略将待分析的汉字串与 一个“充分大的”机器词典中的词条进行配,若在词典中找到某个字符串,则匹配成功(识别出一个词)。按照扫描方向的不同,串匹配分词方法可以分为正向匹配 和逆向匹配;按照不同长度优先匹配的情况,可以分为最大(最长)匹配和最小(最短)匹配;按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与 标注相结合的一体化方法。常用的几种机械分词方法如下: 1)正向最大匹配法(由左到右的方向); 2)逆向最大匹配法(由右到左的方向); 3)最少切分(使每一句中切出的词数最小)。 还可以将上述各种方法相互组合,例如,可以将正向最大匹配方法和逆向最大匹配方法结合起来构成双向匹配法。由于汉语单字成词的特点,正向最小匹配和逆向 最小匹配一般很少使用。一般说来,逆向匹配的切分精度略高于正向匹配,遇到的歧义现象也较少。统计结果表明,单纯使用正向最大匹配的错误率为1/169, 单纯使用逆向最大匹配的错误率为1/245。但这种精度还远远不能满足实际的需要。实际使用的分词系统,都是把机械分词作为一种初分手段,还需通过利用各 种其它的语言信息来进一步提高切分的准确率。 一种方法是改进扫描方式,称为特征扫描或标志切分,优先在待分析字符串中识别和切分出一些带有明 显特征的词,以这些词作为断点,可将原字符串分为较小的串再来进机械分词,从而减少匹配的错误率。另一种方法是将分词和词类标注结合起来,利用丰富的词类 信息对分词决策提供帮助,并且在标注过程中又反过来对分词结果进行检验、调整,从而极大地提高切分的准确率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值