📄 word.php
字号:
<?php
class WordSeg {
private $wordArr = array();//存储词典中的词
private $words = array();//存储词分出来的词
private $splitLen;//设置的词长,如上个例子中的4,即一次取出4个汉字
/**
* 构造函数主要是从词典中读出词,并且存入$this->wordArr数组中
* 存入后要排序,为了以后的二分查找
* @param $path变量就是字典存储的路径
*/
public function WordSeg($path){
$handle = fopen($path,r);
if($handle){
$i = 0;
while(!feof($handle)){
$buffer = fgets($handle, 12);
//echo trim($buffer)."<br>";
$this->wordArr[$i] = trim($buffer);
$i++;
}
//排序
sort ($this->wordArr);
//重新设置数组的下标
reset ($this->wordArr);
}else{
echo("the keywords file path is not right");
}
}
/**
* 主要设置词长,即一次取出几个汉字,默认为2。在php中一个汉字是占两个字节的,所以默认值为4
* $len : 词的长度
*/
public function setLen($len = 4){
$this->splitLen = $len;
}
/**
* 得到这个词长
*/
public function getLen(){
return $this->splitLen;
}
/**
* 为了提高查询的速度在词典中进行匹配的时候是采用二分查找的方法
* 这种查找方法在词典文件很大的时候可以提高效率
* 为了使用这种查找方法必须的在把词典文件读入数组中时必须要排序的
* 二分查找要求数组中的是按照顺序排列的
* @param $word : 要匹配的词
*/
public function findString($word){
$max = count($this->wordArr);
$min = 1;
while($min <= $max){
$mid = (int)(($max + $min)/2);
//echo 'id : '.$mid." : ".$this->wordArr[$mid - 1];
if($this->wordArr[$mid-1] > $word)
$max = $mid - 1;
else if($this->wordArr[$mid-1] == $word){
//echo "find word :".$word;
$this->words[] = $word;
return true;
}
else
$min = $mid + 1;
}
return false;
/**/
}
/**
* 这是最主要的方法,分词的最大逆向匹配方法
* 此程序的方法还是按照上面的例子来做的
* @param $wordString : 要分词的字符串
*/
public function wordSplit($wordString){
$len = strlen($wordString);
//echo $len;
//echo $this->splitLen;
for($i = $len; $i > 2; $i = $i - 2){
$subWord = $this->getWords($wordString,$i,$this->splitLen * 2);
//echo " fu :".$subWord."<Br>";
if($this->findString($subWord)){
//find
//echo "find : ".$subWord;
//如果找到就从从下一个开始找
$i = $i - $this->splitLen * 2 + 2;
}else{
//not find
//如果找不到,则去掉取得字符串的最前面的一个字,直到找到或剩下两个汉字为止
$wordLen = ($i > $this->splitLen * 2) ? $this->splitLen*2 : $i;
//echo $wordLen."<Br>";
for($j = $wordLen - 2; $j > 2; $j = $j -2){
$subWord = $this->getWords($wordString,$i,$j);
//echo " su :".$subWord."<Br>";
if($this->findString($subWord)){
//find
//echo "find : ".$subWord;
$i = $i - $j + 2;
break;
}
}//end for
}
}//end for
}
/**
* 截取字符串的函数,分词的时候要不断的截取字符串
* @param $wordString : 要截取字符串的母串,所截取的字符串都是从$wordString中截取的
* @param $start : 截取的开始字符
* @param $len : 要截取的长度
*/
private function getWords($wordString,$end,$len){
if(($end - $len) <= 0){
//如果截取的长度大于$wordString的长度时,取从0,到要开始截取的字符就可以了
//由于时逆向截取,所以真正的开始字符是$end-$len
return substr($wordString,0,$end);
}
else{
//否则就从$start = $end-$len开始截取,截取$len个字符
return substr($wordString,($end - $len),$len);
}
}
/**
* 取出得到的分词结果
*/
public function getSplitWords(){
return $this->words;
}
}
//我的词典位置是在d:\word下,文件名是words.dict
$word = new WordSeg('d:\word\words.dict');
$word->setLen();
$word->wordSplit('则从这个句子的第');
$wordArr = $word->getSplitWords();
foreach($wordArr as $value){
echo 'word is : '.$value."<br>";
}
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -