幽冥大陆(九十三 ) PHP分词服务源码 —东方仙盟练气期

分词服务代码

分词服务是自然语言处理(NLP)领域的核心基础服务,其核心价值在于将非结构化的自然语言文本(如用户评论、电商标题、新闻资讯)拆解为具有语义的最小单位(词语),为上层业务(智能客服、舆情分析、内容推荐、智能检索)提供标准化的语言数据支撑。该服务不仅解决了中文文本无天然分隔符的行业痛点,更能通过精准分词挖掘文本背后的商业价值:例如电商平台通过商品标题分词实现精准搜索匹配,提升 GMV;金融机构借助舆情文本分词识别风险关键词,降低决策成本;企业通过用户评论分词分析核心诉求,优化产品设计。

从实现核心来看,该服务兼顾精准性实用性:技术层面融合规则分词(基于词典匹配)与机器学习分词(CRF、BERT 模型),既保证通用场景准确率>98%,又支持行业定制化词典(如医疗、金融专属词汇);工程层面采用高并发架构设计,支持每秒万级文本处理,响应时延<50ms,满足大规模商业场景的实时性需求;商业层面支持 SaaS 化订阅与私有化部署,按调用量计费的模式降低中小企业使用门槛,同时通过分词结果的语义标注增值服务,进一步提升商业变现能力。

核心价值与实现总结

  1. 商业价值核心:以标准化分词能力打通文本数据价值转化链路,直接赋能搜索、推荐、风控等核心业务的效率与收益提升,且支持灵活的商业化交付模式。

  2. 技术实现核心:规则 + 机器学习双引擎保障分词精准度,高并发架构满足商业场景的性能要求,定制化词典适配不同行业的专属需求。

  3. 行业落地核心:解决中文文本处理的基础痛点,成为所有 NLP 上层商业应用的必备底层能力,具备广泛的场景适配性与变现潜力

    <?php

    class 未来之窗_分词服务 {
    void close(void);
    void set_charset(string charset);
    bool set_dict(string dict_path);
    void set_rule(string rule_path);
    void set_ignore(bool set);
    void set_multi(int level);
    void set_debug(bool set);
    void set_duality(bool set);

    void send_text(string text);
    mixed get_result(void);
    mixed get_tops( [int limit [, string attr]] );

    string version(void);
    };

    * ----------------------------------------------------------------------- */

    /** 词典读取代码 (xdb_r) */
    require_once (dirname(FILE) . '/xdb_r.class.php');

    /** defines for ruleset */
    define ('未来之窗_分词_RULE_MAX', 31); // just 31, PHP do not support unsigined Int
    define ('未来之窗_分词_RULE_SPECIAL', 0x80000000);
    define ('未来之窗_分词_RULE_NOSTATS', 0x40000000);
    define ('未来之窗_分词_ZRULE_NONE', 0x00);
    define ('未来之窗_分词_ZRULE_PREFIX', 0x01);
    define ('未来之窗_分词_ZRULE_SUFFIX', 0x02);
    define ('未来之窗_分词_ZRULE_INCLUDE', 0x04); // with include
    define ('未来之窗_分词_ZRULE_EXCLUDE', 0x08); // with exclude
    define ('未来之窗_分词_ZRULE_RANGE', 0x10); // with znum range

    /** defines for mode of scws <= 0x800 */
    define ('未来之窗_分词_IGN_SYMBOL', 0x01);
    define ('未来之窗_分词_DEBUG', 0x02);
    define ('未来之窗_分词_DUALITY', 0x04);

    /** multi segment policy >= 0x1000 */
    define ('未来之窗_分词_MULTI_NONE', 0x0000); // nothing
    define ('未来之窗_分词_MULTI_SHORT', 0x1000); // split long words to short words from left to right
    define ('未来之窗_分词_MULTI_DUALITY', 0x2000); // split every long words(3 chars?) to two chars
    define ('未来之窗_分词_MULTI_ZMAIN', 0x4000); // split to main single chinese char atr = j|a|n?|v?
    define ('未来之窗_分词_MULTI_ZALL', 0x8000); // attr = ** , all split to single chars
    define ('未来之窗_分词_MULTI_MASK', 0xf000); // mask check for multi set
    define ('未来之窗_分词_ZIS_USED', 0x8000000);

    /** single bytes segment flag (纯单字节字符) */
    define ('未来之窗_分词_PFLAG_WITH_MB', 0x01);
    define ('未来之窗_分词_PFLAG_ALNUM', 0x02);
    define ('未来之窗_分词_PFLAG_VALID', 0x04);
    define ('未来之窗_分词_PFLAG_DIGIT', 0x08);
    define ('未来之窗_分词_PFLAG_ADDSYM', 0x10);

    /** constant var define */
    define ('未来之窗_分词_WORD_FULL', 0x01); // 多字: 整词
    define ('未来之窗_分词_WORD_PART', 0x02); // 多字: 前词段
    define ('未来之窗_分词_WORD_USED', 0x04); // 多字: 已使用
    define ('未来之窗_分词_WORD_RULE', 0x08); // 多字: 自动识别的

    define ('未来之窗_分词_ZFLAG_PUT', 0x02); // 单字: 已使用
    define ('未来之窗_分词_ZFLAG_N2', 0x04); // 单字: 双字名词头
    define ('未来之窗_分词_ZFLAG_NR2', 0x08); // 单字: 词头且为双字人名
    define ('未来之窗_分词_ZFLAG_WHEAD', 0x10); // 单字: 词头
    define ('未来之窗_分词_ZFLAG_WPART', 0x20); // 单字: 词尾或词中
    define ('未来之窗_分词_ZFLAG_ENGLISH', 0x40); // 单字: 夹在中间的英文
    define ('未来之窗_分词_ZFLAG_SYMBOL', 0x80); // 单字: 符号系列

    define ('未来之窗_分词_MAX_EWLEN', 16);
    define ('未来之窗_分词_MAX_ZLEN', 128);

    /** 主类库代码 */
    class 未来之窗_分词服务
    {
    var _未来之窗_词典句柄; // xdb dict handler var _未来之窗_规则集资源; // ruleset resource
    var _未来之窗_规则集数据; // ruleset data var _未来之窗_字符集 = ''; // charset
    var _未来之窗_字符长度表; // zi len table var _未来之窗_分词模式 = 0; // scws mode
    var _未来之窗_待分词文本; // text string var _未来之窗_分词结果;
    var _未来之窗_单字使用标记; // z if used?(duality) var _未来之窗_偏移量 = 0;
    var _未来之窗_文本长度 = 0; var _未来之窗_词结束位置 = 0;
    var _未来之窗_词映射表; var _未来之窗_字映射表;

    复制代码
     // 构造函数
     function __construct($字符集 = 'utf8')
     {
     	$this->_未来之窗_词典句柄 = false;
     	$this->_未来之窗_规则集资源 = $this->_未来之窗_规则集数据 = array();
     	$this->set_charset($字符集);
     }
    
     // FOR PHP5
     //function __construct() { $this->PSCWS4(); }
     function __destruct() { $this->close(); }
    
     // 设置字符集(ztab)
     function set_charset($字符集 = 'utf8')
     {
     	$字符集 = strtolower(trim($字符集));
     	if ($字符集 !== $this->_未来之窗_字符集)
     	{
     		$this->_未来之窗_字符集 = $字符集;
    
     		// charset's mblen map, only for utf-8 & gbk(big5)
     		$this->_未来之窗_字符长度表 = array_fill(0, 0x81, 1);
     		if ($字符集 == 'utf-8' || $字符集 == 'utf8')
     		{
     			// UTF-8
     			$this->_未来之窗_字符长度表 = array_pad($this->_未来之窗_字符长度表, 0xc0, 1);
     			$this->_未来之窗_字符长度表 = array_pad($this->_未来之窗_字符长度表, 0xe0, 2);
     			$this->_未来之窗_字符长度表 = array_pad($this->_未来之窗_字符长度表, 0xf0, 3);
     			$this->_未来之窗_字符长度表 = array_pad($this->_未来之窗_字符长度表, 0xf8, 4);
     			$this->_未来之窗_字符长度表 = array_pad($this->_未来之窗_字符长度表, 0xfc, 5);
     			$this->_未来之窗_字符长度表 = array_pad($this->_未来之窗_字符长度表, 0xfe, 6);
     			$this->_未来之窗_字符长度表[] = 1;
     		}
     		else
     		{
     			// GBK & BIG5
     			$this->_未来之窗_字符长度表 = array_pad($this->_未来之窗_字符长度表, 0xff, 2);
     		}
     		$this->_未来之窗_字符长度表[] = 1;
     	}
     }
     
     
    
     // 设置词典
     function set_dict($文件路径)
     {
     	$未来之窗_XDB实例 = new XDB_R;
     	if($文件路径==""){
     	      //2026-01-6
     	   $文件路径= dirname(__FILE__) . '/dict.utf8.xdb';
     	}
     	if (!$未来之窗_XDB实例->Open($文件路径)) return false;
     	$this->_未来之窗_词典句柄 = $未来之窗_XDB实例;
     }
    
     // 设置规则集
     function set_rule($文件路径)
     {
         //2026-01-6
        if($文件路径==""){
     	   $文件路径= dirname(__FILE__) . '/rules.utf8.ini';
     	}
     	
     	$this->_未来之窗_加载规则集($文件路径);
     }
    
     // 设置忽略符号与无用字符
     function set_ignore($是否忽略)
     {
     	if ($是否忽略 == true) $this->_未来之窗_分词模式 |= 未来之窗_分词_IGN_SYMBOL;
     	else $this->_未来之窗_分词模式 &= ~未来之窗_分词_IGN_SYMBOL;
     }
    
     // 设置复合分词等级 ($level = 0,15)
     function set_multi($等级)
     {
     	$等级 = (intval($等级) << 12);
    
     	$this->_未来之窗_分词模式 &= ~未来之窗_分词_MULTI_MASK;
     	if ($等级 & 未来之窗_分词_MULTI_MASK) $this->_未来之窗_分词模式 |= $等级;
     }
    
     // 设置是否显示分词调试信息
     function set_debug($是否调试)
     {
     	if ($是否调试 == true) $this->_未来之窗_分词模式 |= 未来之窗_分词_DEBUG;
     	else $this->_未来之窗_分词模式 &= ~未来之窗_分词_DEBUG;
     }
    
     // 设置是否自动将散字二元化
     function set_duality($是否二元化)
     {
     	if ($是否二元化 == true) $this->_未来之窗_分词模式 |= 未来之窗_分词_DUALITY;
     	else $this->_未来之窗_分词模式 &= ~未来之窗_分词_DUALITY;
     }
    
     // 设置要分词的文本字符串
     function send_text($文本)
     {
     	$this->_未来之窗_待分词文本 = (string) $文本;
     	$this->_未来之窗_文本长度 = strlen($this->_未来之窗_待分词文本);
     	$this->_未来之窗_偏移量 = 0;
     }
    
     // 取回一批分词结果(需要多次调用, 直到返回 false)
     function get_result()
     {
     	$偏移量 = $this->_未来之窗_偏移量;
     	$文本长度 = $this->_未来之窗_文本长度;
     	$待分词文本 = $this->_未来之窗_待分词文本;
     	$this->_未来之窗_分词结果 = array();
    
     	while (($偏移量 < $文本长度) && (ord($待分词文本[$偏移量]) <= 0x20))
     	{
     		if ($待分词文本[$偏移量] == "\r" || $待分词文本[$偏移量] == "\n")
     		{
     			$this->_未来之窗_偏移量 = $偏移量 + 1;
     			$this->_未来之窗_添加结果($偏移量, 0, 1, 'un');
     			return $this->_未来之窗_分词结果;
     		}
     		$偏移量++;
     	}
     	if ($偏移量 >= $文本长度) return false;
    
     	// try to parse the sentence
     	$this->_未来之窗_偏移量 = $偏移量;
     	$字符 = $待分词文本[$偏移量];
     	$字符ASCII = ord($字符);
     	if ($this->_未来之窗_字符是否为分隔符($字符))
     	{
     		$this->_未来之窗_偏移量++;
     		$this->_未来之窗_添加结果($偏移量, 0, 1, 'un');
     		return $this->_未来之窗_分词结果;
     	}
    
     	$字符长度 = $this->_未来之窗_字符长度表[$字符ASCII];
     	$字符计数 = 1;
     	$单字节标记 = ($字符长度 > 1 ? 未来之窗_分词_PFLAG_WITH_MB : ($this->_未来之窗_是否为字母数字($字符ASCII) ? 未来之窗_分词_PFLAG_ALNUM : 0));
     	while (($偏移量 = ($偏移量 + $字符长度)) < $文本长度)
     	{
     		$字符 = $待分词文本[$偏移量];
     		$字符ASCII = ord($字符);
     		if ($字符ASCII <= 0x20 || $this->_未来之窗_字符是否为分隔符($字符)) break;
     		$字符长度 = $this->_未来之窗_字符长度表[$字符ASCII];
     		if (!($单字节标记 & 未来之窗_分词_PFLAG_WITH_MB))
     		{
     			// pure single-byte -> multibyte (2bytes)
     			if ($字符长度 == 1)
     			{
     				if (($单字节标记 & 未来之窗_分词_PFLAG_ALNUM) && !$this->_未来之窗_是否为字母数字($字符ASCII))
     				$单字节标记 ^= 未来之窗_分词_PFLAG_ALNUM;
     			}
     			else
     			{
     				if (!($单字节标记 & 未来之窗_分词_PFLAG_ALNUM) || $字符计数 > 2) break;
     				$单字节标记 |= 未来之窗_分词_PFLAG_WITH_MB;
     			}
     		}
     		else if (($单字节标记 & 未来之窗_分词_PFLAG_WITH_MB) && $字符长度 == 1)
     		{
     			// mb + single-byte. allowd: alpha+num + 中文
     			if (!$this->_未来之窗_是否为字母数字($字符ASCII)) break;
    
     			$单字节标记 &= ~未来之窗_分词_PFLAG_VALID;
     			for ($索引 = $偏移量+1; $索引 < ($偏移量+3); $索引++)
     			{
     				$字符 = $待分词文本[$索引];
     				$字符ASCII = ord($字符);
     				if (($索引 >= $文本长度) || ($字符ASCII <= 0x20) || ($this->_未来之窗_字符长度表[$字符ASCII] > 1))
     				{
     					$单字节标记 |= 未来之窗_分词_PFLAG_VALID;
     					break;
     				}
     				if (!$this->_未来之窗_是否为字母数字($字符ASCII)) break;
     			}
    
     			if (!($单字节标记 & 未来之窗_分词_PFLAG_VALID)) break;
     			$字符长度 += ($索引 - $偏移量 - 1);
     		}
     		// hightman.070813: add max zlen limit
     		if (++$字符计数 >= 未来之窗_分词_MAX_ZLEN) break;
     	}
    
     	// hightman.070624: 处理半个字的问题
     	if (($字符位置 = $偏移量) > $文本长度)
     	$偏移量 -= $字符长度;
    
     	// do the real segment
     	if ($偏移量 <= $this->_未来之窗_偏移量) return false;
     	else if ($单字节标记 & 未来之窗_分词_PFLAG_WITH_MB) $this->_未来之窗_多字节分词($偏移量, $字符计数);
     	else if (!($单字节标记 & 未来之窗_分词_PFLAG_ALNUM) || (($偏移量 - $this->_未来之窗_偏移量) >= 未来之窗_分词_MAX_EWLEN)) $this->_未来之窗_单字节分词($偏移量);
     	else
     	{
     		$字符计数 = $偏移量 - $this->_未来之窗_偏移量;
     		$this->_未来之窗_添加结果($this->_未来之窗_偏移量, 2.5*log($字符计数), $字符计数, 'en');
     	}
    
     	// reutrn the result
     	$this->_未来之窗_偏移量 = ($字符位置 > $文本长度 ? $文本长度 : $偏移量);
     	if (count($this->_未来之窗_分词结果) == 0)
     	return $this->get_result();
    
     	return $this->_未来之窗_分词结果;
     }
    
     // 取回频率和权重综合最大的前 N 个词
     function get_tops($数量限制 = 10, $属性筛选 = '')
     {
     	$返回结果 = array();
     	if (!$this->_未来之窗_待分词文本) return false;
    
     	$排除模式 = false;
     	$属性列表 = array();
     	if ($属性筛选 != '')
     	{
     		if (substr($属性筛选, 0, 1) == '~')
     		{
     			$属性筛选 = substr($属性筛选, 1);
     			$排除模式 = true;
     		}
     		foreach (explode(',', $属性筛选) as $临时变量)
     		{
     			$临时变量 = strtolower(trim($临时变量));
     			if (!empty($临时变量)) $属性列表[$临时变量] = true;
     		}
     	}
    
     	// save the old offset
     	$原偏移量 = $this->_未来之窗_偏移量;
     	$this->_未来之窗_偏移量 = $计数 = 0;
     	$词列表 = array();
    
     	while ($临时数组 = $this->get_result())
     	{
     		foreach ($临时数组 as $临时项)
     		{
     			if ($临时项['idf'] < 0.2 || substr($临时项['attr'], 0, 1) == '#') continue;
    
     			// check attr filter
     			if (count($属性列表) > 0)
     			{
     				if ($排除模式 == true && !isset($属性列表[$临时项['attr']])) continue;
     				if ($排除模式 == false && isset($属性列表[$临时项['attr']])) continue;
     			}
    
     			// check stopwords
     			$单词 = strtolower($临时项['word']);
     			if ($this->_未来之窗_检查规则位($单词, 未来之窗_分词_RULE_NOSTATS)) continue;
    
     			// put to list
     			if (isset($词列表[$单词]))
     			{
     				$词列表[$单词]['weight'] += $临时项['idf'];
     				$词列表[$单词]['times']++;
     			}
     			else
     			{
     				$词列表[$单词] = array('word'=>$临时项['word'], 'times'=>1, 'weight'=>$临时项['idf'], 'attr'=>$临时项['attr']);
     			}
     		}
     	}
    
     	// restore the offset
     	$this->_未来之窗_偏移量 = $原偏移量;
    
     	// sort it & return
     	$比较函数 = create_function('$a,$b', 'return ($b[\'weight\'] > $a[\'weight\'] ? 1 : -1);');
     	usort($词列表, $比较函数);
     	if (count($词列表) > $数量限制) $词列表 = array_slice($词列表, 0, $数量限制);
    
     	return $词列表;
     }
    
     // 关闭释放资源
     function close()
     {
     	// free the dict
     	if ($this->_未来之窗_词典句柄)
     	{
     		$this->_未来之窗_词典句柄->Close();
     		$this->_未来之窗_词典句柄 = false;
     	}
    
     	// free the ruleset
     	$this->_未来之窗_规则集数据 = array();
     	$this->_未来之窗_规则集资源 = array();
     }
    
     // 版本
     function version()
     {
     	return sprintf('PSCWS/4.0 - by hightman');
     }
    
     ////////////////////////////////////////////
     // these are all private functions
     ////////////////////////////////////////////
     function _未来之窗_加载规则集($文件路径)
     {
     	if (!($文件句柄 = fopen($文件路径, 'r'))) return false;
     	$this->_未来之窗_规则集资源 = array();
    
     	// quick scan to add the name to list
     	$索引1 = $索引2 = 0;
     	while ($缓冲 = fgets($文件句柄, 512))
     	{
     		if (substr($缓冲, 0, 1) != '[' || !($位置 = strpos($缓冲, ']')))
     		continue;
     		if ($位置 == 1 || $位置 > 15) continue;
    
     		$键名 = strtolower(substr($缓冲, 1, $位置 - 1));
     		if (isset($this->_未来之窗_规则集资源[$键名])) continue;
     		$项 = array('tf'=>5.0, 'idf'=>3.5, 'attr'=>'un', 'bit'=>0, 'flag'=>0, 'zmin'=>0, 'zmax'=>0, 'inc'=>0, 'exc'=>0);
     		if ($键名 == 'special') $项['bit'] = 未来之窗_分词_RULE_SPECIAL;
     		else if ($键名 == 'nostats') $项['bit'] = 未来之窗_分词_RULE_NOSTATS;
     		else
     		{
     			$项['bit'] = (1<<$索引2);
     			$索引2++;
     		}
     		$this->_未来之窗_规则集资源[$键名] = $项;
     		if (++$索引1 >= 未来之窗_分词_RULE_MAX)
     		break;
     	}
    
     	// load the ruleset
     	rewind($文件句柄);
     	$按行读取 = false;
     	unset($项);
     	while ($缓冲 = fgets($文件句柄, 512))
     	{
     		$首字符 = substr($缓冲, 0, 1);
     		if ($首字符 == ';') continue;
     		if ($首字符 == '[')
     		{
     			unset($项);
     			if (($位置 = strpos($缓冲, ']')) > 1)
     			{
     				$键名 = strtolower(substr($缓冲, 1, $位置 - 1));
     				if (isset($this->_未来之窗_规则集资源[$键名]))
     				{
     					$按行读取 = true;	// defalut read by line = yes
     					$项 = &$this->_未来之窗_规则集资源[$键名];
     				}
     			}
     			continue;
     		}
    
     		// param set: line|znum|include|exclude|type|tf|idf|attr */
     		if ($首字符 == ':')
     		{
     			$缓冲 = substr($缓冲, 1);
     			if (!($位置 = strpos($缓冲, '='))) continue;
     			list($参数键名, $参数值) = explode('=', $缓冲, 2);
     			$参数键名 = trim($参数键名);
     			$参数值 = trim($参数值);
     			if ($参数键名 == 'line') $按行读取 = (strtolower(substr($参数值, 0, 1)) == 'n' ? false : true);
     			else if ($参数键名 == 'tf') $项['tf'] = floatval($参数值);
     			else if ($参数键名 == 'idf') $项['idf'] = floatval($参数值);
     			else if ($参数键名 == 'attr') $项['attr'] = $参数值;	// 2bytes?
     			else if ($参数键名 == 'znum')
     			{
     				if ($位置 = strpos($参数值, ','))
     				{
     					$项['zmax'] = intval(trim(substr($参数值, $位置+1)));
     					$项['flag'] |= 未来之窗_分词_ZRULE_RANGE;
     					$参数值 = substr($参数值, 0, $位置);
     				}
     				$项['zmin'] = intval($参数值);
     			}
     			else if ($参数键名 == 'type')
     			{
     				if ($参数值 == 'prefix') $项['flag'] |= 未来之窗_分词_ZRULE_PREFIX;
     				if ($参数值 == 'suffix') $项['flag'] |= 未来之窗_分词_ZRULE_SUFFIX;
     			}
     			else if ($参数键名 == 'include' || $参数键名 == 'exclude')
     			{
     				$包含排除标记 = 0;
     				foreach (explode(',', $参数值) as $临时变量)
     				{
     					$临时变量 = strtolower(trim($临时变量));
     					if (!isset($this->_未来之窗_规则集资源[$临时变量])) continue;
     					$包含排除标记 |= $this->_未来之窗_规则集资源[$临时变量]['bit'];
     				}
     				if ($参数键名 == 'include')
     				{
     					$项['inc'] |= $包含排除标记;
     					$项['flag'] |= 未来之窗_分词_ZRULE_INCLUDE;
     				}
     				else
     				{
     					$项['exc'] |= $包含排除标记;
     					$项['flag'] |= 未来之窗_分词_ZRULE_EXCLUDE;
     				}
     			}
     			continue;
     		}
    
     		// read the entries
     		if (!isset($项)) continue;
     		$缓冲 = trim($缓冲);
     		if (empty($缓冲)) continue;
    
     		// save the record
     		if ($按行读取) $this->_未来之窗_规则集数据[$缓冲] = &$项;
     		else
     		{
     			$长度 = strlen($缓冲);
     			for ($偏移量 = 0; $偏移量 < $长度; )
     			{
     				$ASCII值 = ord(substr($缓冲, $偏移量, 1));
     				$字符长度 = $this->_未来之窗_字符长度表[$ASCII值];
     				if ($偏移量 + $字符长度 >= $长度) break;
     				$字符 = substr($缓冲, $偏移量, $字符长度);
     				$this->_未来之窗_规则集数据[$字符] = &$项;
     				$偏移量 += $字符长度;
     			}
     		}
     	}
     }
    
     // get the ruleset
     function _未来之窗_获取规则($字符串)
     {
     	if (!isset($this->_未来之窗_规则集数据[$字符串])) return false;
     	return $this->_未来之窗_规则集数据[$字符串];
     }
    
     // check the bit with str
     function _未来之窗_检查规则位($字符串, $位标记)
     {
     	if (!isset($this->_未来之窗_规则集数据[$字符串])) return false;
     	$位标记2 = $this->_未来之窗_规则集数据[$字符串]['bit'];
     	return ($位标记 & $位标记2 ? true : false);
     }
    
     // check the rule include | exclude
     function _未来之窗_检查规则($规则, $字符串)
     {
     	if (($规则['flag'] & 未来之窗_分词_ZRULE_INCLUDE) && !$this->_未来之窗_检查规则位($字符串, $规则['bit']))
     	return false;
     	if (($规则['flag'] & 未来之窗_分词_ZRULE_EXCLUDE) && $this->_未来之窗_检查规则位($字符串, $规则['bit']))
     	return false;
     	return true;
     }
    
     // bulid res
     function _未来之窗_添加结果($偏移, $权重, $长度, $属性)
     {
     	$单词 = substr($this->_未来之窗_待分词文本, $偏移, $长度);
     	$项 = array('word'=>$单词, 'off'=>$偏移, 'idf'=>$权重, 'len'=>$长度, 'attr'=>$属性);
     	$this->_未来之窗_分词结果[] = $项;
     }
    
     // alpha, numeric check by ORD value
     function _未来之窗_是否为字母数字($ASCII值)
     {
     	return (($ASCII值>=48&&$ASCII值<=57)||($ASCII值>=65&&$ASCII值<=90)||($ASCII值>=97&&$ASCII值<=122));
     }
    
     function _未来之窗_是否为字母($ASCII值)
     {
     	return (($ASCII值>=65&&$ASCII值<=90)||($ASCII值>=97&&$ASCII值<=122));
     }
    
     function _未来之窗_是否为大写字母($ASCII值)
     {
     	return ($ASCII值>=65&&$ASCII值<=90);
     }
    
     function _未来之窗_是否为数字($ASCII值)
     {
     	return ($ASCII值>=48&&$ASCII值<=57);
     }
    
     function _未来之窗_不满足规则1($标记)
     {
     	return (($标记 & (未来之窗_分词_ZFLAG_SYMBOL|未来之窗_分词_ZFLAG_ENGLISH)) || (($标记 & (未来之窗_分词_ZFLAG_WHEAD|未来之窗_分词_ZFLAG_NR2)) == 未来之窗_分词_ZFLAG_WHEAD));
     }
    
     function _未来之窗_不满足规则2($标记)
     {
     	//return (($标记 & 未来之窗_分词_ZFLAG_ENGLISH) || (($标记 & (未来之窗_分词_ZFLAG_WHEAD|未来之窗_分词_ZFLAG_N2)) == 未来之窗_分词_ZFLAG_WHEAD));
     	return $this->_未来之窗_不满足规则1($标记);
     }
    
     function _未来之窗_字符是否为分隔符($字符)
     {
     	return ($字符=='('||$字符==')'||$字符=='['||$字符==']'||$字符=='{'||$字符=='}'||$字符==':'||$字符=='"');
     }
    
     // query the dict
     function _未来之窗_查询词典($单词)
     {
     	if (!$this->_未来之窗_词典句柄) return false;
     	$值 = $this->_未来之窗_词典句柄->Get($单词);
     	if (!$值) return false;
    
     	$临时数组 = unpack('ftf/fidf/Cflag/a3attr', $值);
     	return $临时数组;
     }
    
     // ssegment, 单字节用语切割
     function _未来之窗_单字节分词($结束位置)
     {
     	$起始位置 = $this->_未来之窗_偏移量;
     	$词长度 = $结束位置 - $起始位置;
    
     	// check special words (need strtoupper)
     	if ($词长度 > 1)
     	{
     		$文本 = strtoupper(substr($this->_未来之窗_待分词文本, $起始位置, $词长度));
     		if ($this->_未来之窗_检查规则位($文本, 未来之窗_分词_RULE_SPECIAL))
     		{
     			$this->_未来之窗_添加结果($起始位置, 9.5, $词长度, 'nz');
     			return;
     		}
     	}
    
     	$文本 = $this->_未来之窗_待分词文本;
    
     	// check brief words such as S.H.E M.R.
     	if ($this->_未来之窗_是否为大写字母(ord($文本[$起始位置])) && $文本[$起始位置+1] == '.')
     	{
     		for ($字符位置 = $起始位置 + 2; $字符位置 < $结束位置; $字符位置++)
     		{
     			if (!$this->_未来之窗_是否为大写字母(ord($文本[$字符位置]))) break;
     			$字符位置++;
     			if ($字符位置 == $结束位置 || $文本[$字符位置] != '.') break;
     		}
     		if ($字符位置 == $结束位置)
     		{
     			$this->_未来之窗_添加结果($起始位置, 7.5, $词长度, 'nz');
     			return;
     		}
     	}
    
     	// 取出单词及标点. 数字允许一个点且下一个为数字,不连续的. 字母允许一个不连续的'
     	while ($起始位置 < $结束位置)
     	{
     		$字符 = $文本[$起始位置++];
     		$ASCII值 = ord($字符);
     		if ($this->_未来之窗_是否为字母数字($ASCII值))
     		{
     			$单字节标记 = $this->_未来之窗_是否为数字($ASCII值) ? 未来之窗_分词_PFLAG_DIGIT : 0;
     			$词长度 = 1;
     			while ($起始位置 < $结束位置)
     			{
     				$字符 = $文本[$起始位置];
     				$ASCII值 = ord($字符);
     				if ($单字节标记 & 未来之窗_分词_PFLAG_DIGIT)
     				{
     					if (!$this->_未来之窗_是否为数字($ASCII值))
     					{
     						if (($单字节标记 & 未来之窗_分词_PFLAG_ADDSYM) || $ASCII值 != 0x2e || !$this->_未来之窗_是否为数字(ord($文本[$起始位置+1])))
     						break;
     						$单字节标记 |= 未来之窗_分词_PFLAG_ADDSYM;
     					}
     				}
     				else
     				{
     					if (!$this->_未来之窗_是否为字母($ASCII值))
     					{
     						if (($单字节标记 & 未来之窗_分词_PFLAG_ADDSYM) || $ASCII值 != 0x27 || !$this->_未来之窗_是否为字母(ord($文本[$起始位置+1])))
     						break;
     						$单字节标记 |= 未来之窗_分词_PFLAG_ADDSYM;
     					}
     				}
     				$起始位置++;
     				if (++$词长度 >= 未来之窗_分词_MAX_EWLEN) break;
     			}
     			$this->_未来之窗_添加结果($起始位置 - $词长度, 2.5*log($词长度), $词长度, 'en');
     		}
     		else if (!($this->_未来之窗_分词模式 & 未来之窗_分词_IGN_SYMBOL))
     		{
     			$this->_未来之窗_添加结果($起始位置-1, 0, 1, 'un');
     		}
     	}
     }
    
     // get one z by ZMAP
     function _未来之窗_获取字串($起始索引, $结束索引 = -1)
     {
     	if ($结束索引 == -1) $结束索引 = $起始索引;
     	return substr($this->_未来之窗_待分词文本, $this->_未来之窗_字映射表[$起始索引]['start'], $this->_未来之窗_字映射表[$结束索引]['end'] - $this->_未来之窗_字映射表[$起始索引]['start']);
     }
    
     // mget_word
     function _未来之窗_获取单词($起始索引, $结束索引)
     {
     	$词映射表 = $this->_未来之窗_词映射表;
    
     	if (!($词映射表[$起始索引][$起始索引]['flag'] & 未来之窗_分词_ZFLAG_WHEAD)) return $起始索引;
     	for ($返回索引 = $起始索引, $索引 = $起始索引+1; $索引 <= $结束索引; $索引++)
     	{
     		if ($词映射表[$起始索引][$索引] && ($词映射表[$起始索引][$索引]['flag'] & 未来之窗_分词_WORD_FULL)) $返回索引 = $索引;
     	}
     	return $返回索引;
     }
    
     // mset_word
     function _未来之窗_设置单词($起始索引, $结束索引)
     {
     	$词映射表 = $this->_未来之窗_词映射表;
     	$字映射表 = $this->_未来之窗_字映射表;
     	$项 = $词映射表[$起始索引][$结束索引];
    
     	// hightman.070705: 加入 item == null 判断, 防止超长词(255字以上)unsigned char溢出
     	if (($项 == false) || (($this->_未来之窗_分词模式 & 未来之窗_分词_IGN_SYMBOL)
     	&& !($项['flag'] & 未来之窗_分词_ZFLAG_ENGLISH) && $项['attr'] == 'un'))
     	{
     		return;
     	}
    
     	// hightman.070701: 散字自动二元聚合
     	if ($this->_未来之窗_分词模式 & 未来之窗_分词_DUALITY)
     	{
     		$索引 = $this->_未来之窗_单字使用标记;
     		if ($起始索引 == $结束索引 && !($项['flag'] & 未来之窗_分词_ZFLAG_ENGLISH) && $项['attr'] == 'un')
     		{
     			$this->_未来之窗_单字使用标记 = $起始索引;
     			if ($索引 < 0) return;
    
     			$起始索引 = ($索引 & ~未来之窗_分词_ZIS_USED);
     			if (($起始索引 != ($结束索引-1)) || (!($索引 & 未来之窗_分词_ZIS_USED) && $this->_未来之窗_词结束位置 == $起始索引))
     			{
     				$this->_未来之窗_添加结果($字映射表[$起始索引]['start'], $词映射表[$起始索引][$起始索引]['idf'], $字映射表[$起始索引]['end'] - $字映射表[$起始索引]['start'], $词映射表[$起始索引][$起始索引]['attr']);
     				if ($起始索引 != ($结束索引-1)) return;
     			}
     			$this->_未来之窗_单字使用标记 |= 未来之窗_分词_ZIS_USED;
     		}
     		else
     		{
     			if (($索引 >= 0) && (!($索引 & 未来之窗_分词_ZIS_USED) || ($结束索引 > $起始索引)))
     			{
     				$索引 &= ~未来之窗_分词_ZIS_USED;
     				$this->_未来之窗_添加结果($字映射表[$索引]['start'], $词映射表[$索引][$索引]['idf'], $字映射表[$索引]['end'] - $字映射表[$索引]['start'], $词映射表[$索引][$索引]['attr']);
     			}
     			if ($结束索引 > $起始索引) $this->_未来之窗_词结束位置 = $结束索引 + 1;
     			$this->_未来之窗_单字使用标记 = -1;
     		}
     	}
    
     	// save the res
     	$this->_未来之窗_添加结果($字映射表[$起始索引]['start'], $项['idf'], $字映射表[$结束索引]['end'] - $字映射表[$起始索引]['start'], $项['attr']);
    
     	// hightman.070902: multi segment
     	// step1: split to short words
     	if (($结束索引-$起始索引) > 1)
     	{
     		$索引 = $起始索引;
     		if ($this->_未来之窗_分词模式 & 未来之窗_分词_MULTI_SHORT)
     		{
     			while ($索引 < $结束索引)
     			{
     				$当前索引 = $索引;
     				for ($循环索引 = $索引 + 1; $循环索引 <= $结束索引; $循环索引++)
     				{
     					if ($循环索引 == $结束索引 && $索引 == $起始索引) break;
     					$项 = $词映射表[$索引][$循环索引];
     					if ($项 && ($项['flag'] & 未来之窗_分词_WORD_FULL))
     					{
     						$当前索引 = $循环索引;
     						$this->_未来之窗_添加结果($字映射表[$索引]['start'], $项['idf'], $字映射表[$循环索引]['end'] - $字映射表[$索引]['start'], $项['attr']);
     						if (!($项['flag'] & 未来之窗_分词_WORD_PART)) break;
     					}
     				}
     				if ($当前索引 == $索引)
     				{
     					if ($索引 == $起始索引) break;
     					$项 = $词映射表[$索引][$索引];
     					$this->_未来之窗_添加结果($字映射表[$索引]['start'], $项['idf'], $字映射表[$索引]['end'] - $字映射表[$索引]['start'], $项['attr']);
     				}
     				if (($索引 = ($当前索引+1)) == $结束索引)
     				{
     					$索引--;
     					break;
     				}
     			}
     		}
     		if ($this->_未来之窗_分词模式 & 未来之窗_分词_MULTI_DUALITY)
     		{
     			while ($索引 < $结束索引)
     			{
     				$this->_未来之窗_添加结果($字映射表[$索引]['start'], $词映射表[$索引][$索引]['idf'], $字映射表[$索引+1]['end'] - $字映射表[$索引]['start'], $词映射表[$索引][$索引]['attr']);
     				$索引++;
     			}
     		}
     	}
    
     	// step2, split to single char
     	if (($结束索引 > $起始索引) && ($this->_未来之窗_分词模式 & (未来之窗_分词_MULTI_ZMAIN|未来之窗_分词_MULTI_ZALL)))
     	{
     		if (($结束索引 - $起始索引) == 1 && !$词映射表[$起始索引][$结束索引])
     		{
     			if ($词映射表[$起始索引][$起始索引]['flag'] & 未来之窗_分词_ZFLAG_PUT) $起始索引++;
     			else $词映射表[$起始索引][$起始索引]['flag'] |= 未来之窗_分词_ZFLAG_PUT;
     			$词映射表[$结束索引][$结束索引]['flag'] |= 未来之窗_分词_ZFLAG_PUT;
     		}
     		do
     		{
     			if ($词映射表[$起始索引][$起始索引]['flag'] & 未来之窗_分词_ZFLAG_PUT) continue;
     			if (!($this->_未来之窗_分词模式 & 未来之窗_分词_MULTI_ZALL) && !strchr("jnv", substr($词映射表[$起始索引][$起始索引]['attr'],0,1))) continue;
     			$this->_未来之窗_添加结果($字映射表[$起始索引]['start'], $词映射表[$起始索引][$起始索引]['idf'], $字映射表[$起始索引]['end'] - $字映射表[$起始索引]['start'], $词映射表[$起始索引][$起始索引]['attr']);
     		}
     		while (++$起始索引 <= $结束索引);
     	}
     }
    
     // mseg_zone
     function _未来之窗_分词区域处理($起始索引, $结束索引)
     {
     	$权重 = $新权重 = 0.0;
     	$词映射表 = &$this->_未来之窗_词映射表;
     	$字映射表 = $this->_未来之窗_字映射表;
     	$最优路径 = $新路径 = false;
    
     	for ($索引x = $索引i = $起始索引; $索引i <= $结束索引; $索引i++)
     	{
     		$索引j = $this->_未来之窗_获取单词($索引i, $结束索引);
     		if ($索引j == $索引i || $索引j <= $索引x || (/* $索引i > $索引x && */($词映射表[$索引i][$索引j]['flag'] & 未来之窗_分词_WORD_USED))) continue;
    
     		// one word only
     		if ($索引i == $起始索引 && $索引j == $结束索引)
     		{
     			$最优路径 = array($索引j - $索引i, 0xff);
     			break;
     		}
     		if ($索引i != $起始索引 && ($词映射表[$索引i][$索引j]['flag'] & 未来之窗_分词_WORD_RULE)) continue;
    
     		// create the new path
     		$词映射表[$索引i][$索引j]['flag'] |= 未来之窗_分词_WORD_USED;
     		$新权重 = $词映射表[$索引i][$索引j]['tf'] * ($索引j - $索引i + 1);
     		if ($索引i == $起始索引) $新权重 *= 1.2;
     		else if ($索引j == $结束索引) $新权重 *= 1.4;
    
     		// create the npath
     		if ($新路径 == false)
     		$新路径 = array_fill(0, $结束索引-$起始索引+2, 0xff);
    
     		// lookfor backward
     		$索引x = 0;
     		for ($索引m = $起始索引; $索引m < $索引i; $索引m = $索引n+1)
     		{
     			$索引n = $this->_未来之窗_获取单词($索引m, $索引i-1);
     			$新权重 *= $词映射表[$索引m][$索引n]['tf'] * ($索引n-$索引m+1);
     			$新路径[$索引x++] = $索引n - $索引m;
     			if ($索引n > $索引m) $词映射表[$索引m][$索引n]['flag'] |= 未来之窗_分词_WORD_USED;
     		}
    
     		// my self
     		$新路径[$索引x++] = $索引j - $索引i;
    
     		// lookfor forward
     		for ($索引m = $索引j+1; $索引m <= $结束索引; $索引m = $索引n+1)
     		{
     			$索引n = $this->_未来之窗_获取单词($索引m, $结束索引);
     			$新权重 *= $词映射表[$索引m][$索引n]['tf'] * ($索引n-$索引m+1);
     			$新路径[$索引x++] = $索引n - $索引m;
     			if ($索引n > $索引m) $词映射表[$索引m][$索引n]['flag'] |= 未来之窗_分词_WORD_USED;
     		}
    
     		$新路径[$索引x] = 0xff;
     		$新权重 /= pow($索引x-1,4);
    
     		// draw the path for debug
     		if ($this->_未来之窗_分词模式 & 未来之窗_分词_DEBUG)
     		{
     			printf("PATH by keyword = %s, (weight=%.4f):\n", $this->_未来之窗_获取字串($索引i, $索引j), $新权重);
     			for ($索引x = 0, $索引m = $起始索引; ($索引n = $新路径[$索引x]) != 0xff; $索引x++)
     			{
     				$索引n += $索引m;
     				echo $this->_未来之窗_获取字串($索引m, $索引n) . " ";
     				$索引m = $索引n + 1;
     			}
     			echo "\n--\n";
     		}
    
     		$索引x = $索引j;
    
     		// check better path
     		if ($新权重 > $权重)
     		{
     			$权重 = $新权重;
     			$交换变量 = $最优路径;
     			$最优路径 = $新路径;
     			$新路径 = $交换变量;
     			unset($交换变量);
     		}
     	}
    
     	// set the result, mpath != NULL
     	if ($最优路径 == false) return;
     	for ($索引x = 0, $索引m = $起始索引; ($索引n = $最优路径[$索引x]) != 0xff; $索引x++)
     	{
     		$索引n += $索引m;
     		$this->_未来之窗_设置单词($索引m, $索引n);
     		$索引m = $索引n + 1;
     	}
     }
    
     // msegment(重点函数)
     function _未来之窗_多字节分词($结束位置, $字符计数)
     {
     	$this->_未来之窗_词映射表 = array_fill(0, $字符计数, array_fill(0, $字符计数, false));
     	$this->_未来之窗_字映射表 = array_fill(0, $字符计数, false);
     	$词映射表 = &$this->_未来之窗_词映射表;
     	$字映射表 = &$this->_未来之窗_字映射表;
     	$待分词文本 = $this->_未来之窗_待分词文本;
     	$起始位置 = $this->_未来之窗_偏移量;
     	$this->_未来之窗_单字使用标记 = -1;
    
     	// load the zmap
     	for ($索引i = 0; $起始位置 < $结束位置; $索引i++)
     	{
     		$字符 = $待分词文本[$起始位置];
     		$ASCII值 = ord($字符);
     		$字符长度 = $this->_未来之窗_字符长度表[$ASCII值];
     		if ($字符长度 == 1)
     		{
     			while ($起始位置++ < $结束位置)
     			{
     				$ASCII值 = ord($待分词文本[$起始位置]);
     				if ($this->_未来之窗_字符长度表[$ASCII值] > 1) break;
     				$字符长度++;
     			}
     			$词映射表[$索引i][$索引i] = array('tf'=>0.5, 'idf'=>0, 'flag'=>未来之窗_分词_ZFLAG_ENGLISH, 'attr'=>'un');
     		}
     		else
     		{
     			$查询结果 = $this->_未来之窗_查询词典(substr($待分词文本, $起始位置, $字符长度));
     			if (!$查询结果) $词映射表[$索引i][$索引i] = array('tf'=>0.5, 'idf'=>0, 'flag'=>0, 'attr'=>'un');
     			else
     			{
     				if (substr($查询结果['attr'],0,1) == '#') $查询结果['flag'] |= 未来之窗_分词_ZFLAG_SYMBOL;
     				$词映射表[$索引i][$索引i] = $查询结果;
     			}
     			$起始位置 += $字符长度;
     		}
    
     		$字映射表[$索引i] = array('start'=>$起始位置-$字符长度, 'end'=>$起始位置);
     	}
    
     	// fixed real zlength
     	$字符计数 = $索引i;
    
     	// create word query table
     	for ($索引i = 0; $索引i < $字符计数; $索引i++)
     	{
     		$索引k = 0;
     		for ($索引j = $索引i+1; $索引j < $字符计数; $索引j++)
     		{
     			$查询结果 = $this->_未来之窗_查询词典($this->_未来之窗_获取字串($索引i, $索引j));
     			if (!$查询结果) break;
    
     			$字符标记 = $查询结果['flag'];
     			if ($字符标记 & 未来之窗_分词_WORD_FULL)
     			{
     				$词映射表[$索引i][$索引j] = $查询结果;
     				$词映射表[$索引i][$索引i]['flag'] |= 未来之窗_分词_ZFLAG_WHEAD;
    
     				for ($索引k = $索引i+1; $索引k <= $索引j; $索引k++) $词映射表[$索引k][$索引k]['flag'] |= 未来之窗_分词_ZFLAG_WPART;
     			}
     			if (!($字符标记 & 未来之窗_分词_WORD_PART)) break;
     		}
    
     		if ($索引k--)
     		{
     			// set nr2 to some short name
     			if ($索引k == ($索引i+1))
     			{
     				if ($词映射表[$索引i][$索引k]['attr'] == 'nr') $词映射表[$索引i][$索引i]['flag'] |= 未来之窗_分词_ZFLAG_NR2;
     				//if (substr($词映射表[$索引i][$索引k]['attr'], 0, 1) == 'n') $词映射表[$索引i][$索引i]['flag'] |= 未来之窗_分词_ZFLAG_N2;
     			}
    
     			// clean the PART flag for the last word
     			if ($索引k < $索引j) $词映射表[$索引i][$索引k]['flag'] ^= 未来之窗_分词_WORD_PART;
     		}
     	}
    
     	// try to do the ruleset match
     	// for name & zone & chinese numeric
     	if (count($this->_未来之窗_规则集数据) > 0)
     	{
     		// check for 'one word'
     		for ($索引i = 0; $索引i < $字符计数; $索引i++)
     		{
     			if ($this->_未来之窗_不满足规则1($词映射表[$索引i][$索引i]['flag'])) continue;
     			$规则1 = $this->_未来之窗_获取规则($this->_未来之窗_获取字串($索引i));
     			if (!$规则1) continue;
     			$字符长度 = ($规则1['zmin'] > 0 ? $规则1['zmin'] : 1);
    
     			if (($规则1['flag'] & 未来之窗_分词_ZRULE_PREFIX) && ($索引i < ($字符计数 - $字符长度)))
     			{
     				// prefix, check after (zmin~zmax)
     				// 先检查 zmin 字内是否全部符合要求, 再在 zmax 范围内取得符合要求的字
     				for ($字符位置 = 1; $字符位置 <= $字符长度; $字符位置++)
     				{
     					$索引j = $索引i + $字符位置;
     					if ($索引j >= $字符计数 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     				}
     				if ($字符位置 <= $字符长度) continue;
    
     				// no limit znum or limit to a range
     				$索引j = $索引i + $字符位置;
     				while (true)
     				{
     					if ((!$规则1['zmax'] && $规则1['zmin']) || ($规则1['zmax'] && ($字符长度 >= $规则1['zmax']))) break;
     					if ($索引j >= $字符计数 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     					$字符长度++;
     					$索引j++;
     				}
    
     				// 注意原来2字人名,识别后仍为2字的情况
     				if ($词映射表[$索引i][$索引i]['flag'] & 未来之窗_分词_ZFLAG_NR2)
     				{
     					if ($字符长度 == 1) continue;
     					$词映射表[$索引i][$索引i+1]['flag'] |= 未来之窗_分词_WORD_PART;
     				}
    
     				// ok, got: i & clen
     				$索引k = $索引i + $字符长度;
     				$词映射表[$索引i][$索引k] = array('tf'=>$规则1['tf'], 'idf'=>$规则1['idf'], 'flag'=>(未来之窗_分词_WORD_RULE|未来之窗_分词_WORD_FULL), 'attr'=>$规则1['attr']);
     				$词映射表[$索引i][$索引i]['flag'] |= 未来之窗_分词_ZFLAG_WHEAD;
     				for ($索引j = $索引i+1; $索引j <= $索引k; $索引j++) $词映射表[$索引j][$索引j]['flag'] |= 未来之窗_分词_ZFLAG_WPART;
    
     				if (!($词映射表[$索引i][$索引i]['flag'] & 未来之窗_分词_ZFLAG_WPART)) $索引i = $索引k;
     				continue;
     			}
    
     			if (($规则1['flag'] & 未来之窗_分词_ZRULE_SUFFIX) && ($索引i >= $字符长度))
     			{
     				// suffix, check before
     				for ($字符位置 = 1; $字符位置 <= $字符长度; $字符位置++)
     				{
     					$索引j = $索引i - $字符位置;
     					if ($索引j < 0 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     				}
     				if ($字符位置 <= $字符长度) continue;
    
     				// no limit znum or limit to a range
     				$索引j = $索引i - $字符位置;
     				while (true)
     				{
     					if ((!$规则1['zmax'] && $规则1['zmin']) || ($规则1['zmax'] && ($字符长度 >= $规则1['zmax']))) break;
     					if ($索引j < 0 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     					$字符长度++;
     					$索引j--;
     				}
    
     				// ok, got: i & clen (maybe clen=1 & [k][i] isset)
     				$索引k = $索引i - $字符长度;
     				if ($词映射表[$索引k][$索引i] != false) continue;
     				$词映射表[$索引k][$索引i] = array('tf'=>$规则1['tf'], 'idf'=>$规则1['idf'], 'flag'=>未来之窗_分词_WORD_FULL, 'attr'=>$规则1['attr']);
     				$词映射表[$索引k][$索引k]['flag'] |= 未来之窗_分词_ZFLAG_WHEAD;
     				for ($索引j = $索引k+1; $索引j <= $索引i; $索引j++)
     				{
     					$词映射表[$索引j][$索引j]['flag'] |= 未来之窗_分词_ZFLAG_WPART;
     					if (($索引j != $索引i) && ($词映射表[$索引k][$索引j] != false)) $词映射表[$索引k][$索引j]['flag'] |= 未来之窗_分词_WORD_PART;
     				}
     				continue;
     			}
     		}
    
     		// check for 'two words' (such as: 欧阳** , **西路)
     		for ($索引i = $字符计数 - 2; $索引i >= 0; $索引i--)
     		{
     			// with value ==> must be have SCWS_WORD_FULL, so needn't check it ag.
     			if (($词映射表[$索引i][$索引i+1] == false) || ($词映射表[$索引i][$索引i+1]['flag'] & 未来之窗_分词_WORD_PART)) continue;
    
     			$索引k = $索引i+1;
     			$规则1 = $this->_未来之窗_获取规则($this->_未来之窗_获取字串($索引i, $索引k));
     			if (!$规则1) continue;
    
     			$字符长度 = $规则1['zmin'] > 0 ? $规则1['zmin'] : 1;
     			if (($规则1['flag'] & 未来之窗_分词_ZRULE_PREFIX) && ($索引k < ($字符计数 - $字符长度)))
     			{
     				for ($字符位置 = 1; $字符位置 <= $字符长度; $字符位置++)
     				{
     					$索引j = $索引k + $字符位置;
     					if ($索引j >= $字符计数 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     				}
     				if ($字符位置 <= $字符长度) continue;
    
     				// no limit znum or limit to a range
     				$索引j = $索引k + $字符位置;
     				while (true)
     				{
     					if ((!$规则1['zmax'] && $规则1['zmin']) || ($规则1['zmax'] && ($字符长度 >= $规则1['zmax']))) break;
     					if ($索引j >= $字符计数 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     					$字符长度++;
     					$索引j++;
     				}
    
     				// ok, got: i & clen
     				$索引k = $索引k + $字符长度;
     				$词映射表[$索引i][$索引k] = array('tf'=>$规则1['tf'], 'idf'=>$规则1['idf'], 'flag'=>未来之窗_分词_WORD_FULL, 'attr'=>$规则1['attr']);
     				$词映射表[$索引i][$索引i+1]['flag'] |= 未来之窗_分词_WORD_PART;
     				for ($索引j = $索引i+2; $索引j <= $索引k; $索引j++) $词映射表[$索引j][$索引j]['flag'] |= 未来之窗_分词_ZFLAG_WPART;
     				$索引i--;
     				continue;
     			}
    
     			if (($规则1['flag'] & 未来之窗_分词_ZRULE_SUFFIX) && ($索引i >= $字符长度))
     			{
     				// suffix, check before
     				for ($字符位置 = 1; $字符位置 <= $字符长度; $字符位置++)
     				{
     					$索引j = $索引i - $字符位置;
     					if ($索引j < 0 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     				}
     				if ($字符位置 <= $字符长度) continue;
    
     				// no limit znum or limit to a range
     				$索引j = $索引i - $字符位置;
     				while (true)
     				{
     					if ((!$规则1['zmax'] && $规则1['zmin']) || ($规则1['zmax'] && ($字符长度 >= $规则1['zmax']))) break;
     					if ($索引j < 0 || $this->_未来之窗_不满足规则2($词映射表[$索引j][$索引j]['flag'])) break;
     					if (!$this->_未来之窗_检查规则($规则1, $this->_未来之窗_获取字串($索引j))) break;
     					$字符长度++;
     					$索引j--;
     				}
    
     				// ok, got: i & clen (maybe clen=1 & [k][i] isset)
     				$索引k = $索引i - $字符长度;
     				$索引i = $索引i + 1;
     				$词映射表[$索引k][$索引i] = array('tf'=>$规则1['tf'], 'idf'=>$规则1['idf'], 'flag'=>未来之窗_分词_WORD_FULL, 'attr'=>$规则1['attr']);
     				$词映射表[$索引k][$索引k]['flag'] |= 未来之窗_分词_ZFLAG_WHEAD;
     				for ($索引j = $索引k+1; $索引j <= $索引i; $索引j++)
     				{
     					$词映射表[$索引j][$索引j]['flag'] |= 未来之窗_分词_ZFLAG_WPART;
     					if ($词映射表[$索引k][$索引j] != false) $词映射表[$索引k][$索引j]['flag'] |= 未来之窗_分词_WORD_PART;
     				}
     				$索引i -= ($字符长度+1);
     				continue;
     			}
     		}
     	}
    
     	// do the segment really
     	// find the easy break point
     	for ($索引i = 0, $索引j = 0; $索引i < $字符计数; $索引i++)
     	{
     		if ($词映射表[$索引i][$索引i]['flag'] & 未来之窗_分词_ZFLAG_WPART) continue;
     		if ($索引i > $索引j) $this->_未来之窗_分词区域处理($索引j, $索引i-1);
    
     		$索引j = $索引i;
     		if (!($词映射表[$索引i][$索引i]['flag'] & 未来之窗_分词_ZFLAG_WHEAD))
     		{
     			$this->_未来之窗_设置单词($索引i, $索引i);
     			$索引j++;
     		}
     	}
    
     	// the lastest zone
     	if ($索引i > $索引j) $this->_未来之窗_分词区域处理($索引j, $索引i-1);
    
     	// the last single for duality
     	if (($this->_未来之窗_分词模式 & 未来之窗_分词_DUALITY) && ($this->_未来之窗_单字使用标记 >= 0) && !($this->_未来之窗_单字使用标记 & 未来之窗_分词_ZIS_USED))
     	{
     		$索引i = $this->_未来之窗_单字使用标记;
     		$this->_未来之窗_添加结果($字映射表[$索引i]['start'], $词映射表[$索引i][$索引i]['idf'], $字映射表[$索引i]['end'] - $字映射表[$索引i]['start'], $词映射表[$索引i][$索引i]['attr']);
     	}
     }

    }

阿雪技术观

让我们积极投身于技术共享的浪潮中,不仅仅是作为受益者,更要成为贡献者。无论是分享自己的代码、撰写技术博客,还是参与开源项目的维护和改进,每一个小小的举动都可能成为推动技术进步的巨大力量

Embrace open source and sharing, witness the miracle of technological progress, and enjoy the happy times of humanity! Let's actively join the wave of technology sharing. Not only as beneficiaries, but also as contributors. Whether sharing our own code, writing technical blogs, or participating in the maintenance and improvement of open source projects, every small action may become a huge force driving technological progrss.

相关推荐
t198751281 天前
神经网络控制的多方法融合:PID、模型预测控制(MPC)与自适应策略
人工智能·深度学习·神经网络
青主创享阁1 天前
技术破局制造业民企困局:玄晶引擎的AI赋能路径与实践逻辑
人工智能
智慧化智能化数字化方案1 天前
数据资产管理进阶——解读数据资产管理体系建设【附全文阅读】
大数据·人工智能·数据资产管理·数据资产管理体系建设·数据要素入表
沛沛老爹1 天前
Web开发者快速上手AI Agent:基于Function Calling的12306自动订票系统实战
java·人工智能·agent·web转型
EchoL、1 天前
浅谈当下深度生成模型:从VAE、GAN、Diffusion、Flow Matching到世界模型
人工智能·神经网络·生成对抗网络
凤希AI伴侣1 天前
深度优化与开源力量-凤希AI伴侣-2026年1月6日
人工智能·凤希ai伴侣
deephub1 天前
Agentic RAG:用LangGraph打造会自动修正检索错误的 RAG 系统
人工智能·大语言模型·rag·langgraph
Rabbit_QL1 天前
【Pytorch使用】CUDA 显存管理与 OOM 排查实战:以 PyTorch 联邦学习训练为例
人工智能·pytorch·python
坠金1 天前
方差、偏差
人工智能·机器学习