PHP字典树(Trie树)定义与实现方法示例


Posted in PHP onOctober 09, 2017

本文实例讲述了PHP字典树(Trie树)定义与实现方法。分享给大家供大家参考,具体如下:

Trie树的概念(百度的解释):字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

我的理解是用来做字符串搜索的,每个节点只包含一个字符,比如录入单词"world",则树的结构是:

PHP字典树(Trie树)定义与实现方法示例

这时再录入单词"worab",则树的结构为:

PHP字典树(Trie树)定义与实现方法示例

所以每个节点必须还要一个字段is_end标识是否为结束单词。比如用户输入wor,搜索所有wor开头的单词,假设现在有一个单词就是wor,从"w"开始检索,当检索到"r"的时候需要判断"r"节点的is_end为true,则把wor加入到结果列表,然后继续往下面检索。

PHP实现代码:

<?php
class Node{
  public $value;         // 节点值
  public $is_end = false;    // 是否为结束--是否为某个单词的结束节点
  public $childNode = array();  // 子节点
  /* 添加孩子节点--注意:可以不为引用函数,因为PHP对象赋值本身就是引用赋值 */
  public function &addChildNode($value, $is_end = false){
    $node = $this->searchChildNode($value);
    if(empty($node)){
      // 不存在节点,添加为子节点
      $node = new Node();
      $node->value = $value;
      $this->childNode[] = $node;
    }
    $node->is_end = $is_end;
    return $node;
  }
  /* 查询子节点 */
  public function searchChildNode($value){
    foreach ($this->childNode as $k => $v) {
      if($v->value == $value){
        // 存在节点,返回该节点
        return $this->childNode[$k];
      }
    }
    return false;
  }
}
/* 添加字符串 */
function addString(&$head, $str){
  $node = null;
  for ($i=0; $i < strlen($str); $i++) {
    if($str[$i] != ' '){
      $is_end = $i != (strlen($str) - 1) ? false : true;
      if($i == 0){
        $node = $head->addChildNode($str[$i], $is_end);
      }else{
        $node = $node->addChildNode($str[$i], $is_end);
      }
    }
  }
}
/* 获取所有字符串--递归 */
function getChildString($node, $str_array = array(), $str = ''){
  if($node->is_end == true){
    $str_array[] = $str;
  }
  if(empty($node->childNode)){
    return $str_array;
  }else{
    foreach ($node->childNode as $k => $v) {
      $str_array = getChildString($v, $str_array, $str . $v->value);
    }
    return $str_array;
  }
}
/* 搜索 */
function searchString($node, $str){
  for ($i=0; $i < strlen($str); $i++) {
    if($str[$i] != ' '){
      $node = $node->searchChildNode($str[$i]);
      // print_r($node);
      if(empty($node)){
        // 不存在返回空
        return false;
      }
    }
  }
  return getChildString($node);
}
/* 调用测试开始 */
$head = new Node;  // 树的head
// 添加单词
addString($head, 'hewol');
addString($head, 'hemy');
addString($head, 'heml');
addString($head, 'you');
addString($head, 'yo');
// 获取所有单词
$str_array = getChildString($head);
// 搜索
$search_array = searchString($head, 'hem');
// 循环打印所有搜索结果
foreach ($search_array as $key => $value) {
  echo 'hem' . $value . '<br>'; // 输出带上搜索前缀
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP环境搭建最新方法
Sep 05 PHP
PHP 常用函数库和一些实用小技巧
Jan 01 PHP
简单的移动设备检测PHP脚本代码
Feb 19 PHP
PHP微框架Dispatch简介
Jun 12 PHP
php对关联数组循环遍历的实现方法
Mar 13 PHP
PHP通过API获取手机号码归属地
May 28 PHP
PHP合并数组+号和array_merge的区别
Jun 25 PHP
基于CakePHP实现的简单博客系统实例
Jun 28 PHP
浅析Yii2缓存的使用
May 10 PHP
php-fpm开启状态统计的方法详解
Jun 23 PHP
使用tp框架和SQL语句查询数据表中的某字段包含某值
Oct 18 PHP
PHP大文件分割分片上传实现代码
Dec 09 PHP
PHP完全二叉树定义与实现方法示例
Oct 09 #PHP
PHP实现的折半查询算法示例
Oct 09 #PHP
PHP实现的MD5结合RSA签名算法实例
Oct 07 #PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
Oct 07 #PHP
PHP实现打包下载文件的方法示例
Oct 07 #PHP
PHP基于PDO调用sqlserver存储过程通用方法【基于Yii框架】
Oct 07 #PHP
PHP使用PDO调用mssql存储过程的方法示例
Oct 07 #PHP
You might like
在PHP中使用XML
2006/10/09 PHP
可定制的PHP缩略图生成程式(需要GD库支持)
2007/03/06 PHP
PHP+Ajax 检测网络是否正常实例详解
2016/12/16 PHP
js onpropertychange输入框 事件获取属性
2009/03/26 Javascript
Javascript中Eval函数的使用
2010/03/23 Javascript
JQuery 拾色器插件发布-jquery.icolor.js
2010/10/20 Javascript
在多个页面使用同一个HTML片段的代码
2011/03/04 Javascript
Javascript 面向对象编程(coolshell)
2012/03/18 Javascript
利用window.name实现windowStorage代码分享
2014/01/02 Javascript
兼容Firefox的Javascript XSLT 处理XML文件
2014/12/31 Javascript
微信小程序 animation API详解及实例代码
2016/10/08 Javascript
老生常谈js中0到底是 true 还是 false
2017/03/08 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
详解node+express+ejs+bootstrap构建项目
2017/09/27 Javascript
JS 中document.write()的用法和清空的原因浅析
2017/12/04 Javascript
用ES6写全屏滚动插件的示例代码
2018/05/02 Javascript
vue解决一个方法同时发送多个请求的问题
2018/09/25 Javascript
BootStrap模态框闪退问题实例代码详解
2018/12/10 Javascript
微信小程序使用for循环动态渲染页面操作示例
2018/12/25 Javascript
vue-router 前端路由之路由传值的方式详解
2019/04/30 Javascript
vue路由守卫,限制前端页面访问权限的例子
2019/11/11 Javascript
Python3.2中Print函数用法实例详解
2015/05/19 Python
Python爬虫代理IP池实现方法
2017/01/05 Python
Python中的__slots__示例详解
2017/07/06 Python
Python实现小数转化为百分数的格式化输出方法示例
2017/09/20 Python
Python 把序列转换为元组的函数tuple方法
2019/06/27 Python
python 使用while写猜年龄小游戏过程解析
2019/10/07 Python
Python发送邮件的实例代码讲解
2019/10/16 Python
博朗(Braun)俄罗斯官方商店:德国小家电品牌
2019/09/24 全球购物
俄罗斯购买剧院和演唱会门票网站:Parter.ru
2019/11/09 全球购物
西式婚礼主持词
2014/03/13 职场文书
五分钟演讲稿
2014/04/30 职场文书
作风整顿个人剖析材料
2014/10/06 职场文书
大学生个人简历自荐信
2015/03/06 职场文书
党小组评议意见
2015/06/02 职场文书
八年级作文之感悟亲情
2019/11/20 职场文书