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 图像尺寸调整代码
May 26 PHP
php+ajax做仿百度搜索下拉自动提示框(有实例)
Aug 21 PHP
eAccelerator的安装与使用详解
Jun 13 PHP
php获取$_POST同名参数数组的实现介绍
Jun 30 PHP
php stream_get_meta_data返回值
Sep 29 PHP
PHP中通过fopen()函数访问远程文件示例
Nov 18 PHP
Thinkphp微信公众号支付接口
Aug 04 PHP
php下载文件,添加响应头的简单实例
Sep 22 PHP
浅谈PHP安全防护之Web攻击
Jan 03 PHP
php curl常用的5个经典例子
Jan 20 PHP
PHP实现的多维数组排序算法分析
Feb 10 PHP
tp5(thinkPHP5框架)captcha验证码配置及验证操作示例
May 28 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对MongoDB[NoSQL]数据库的操作
2013/03/01 PHP
$.ajax json数据传递方法
2008/11/19 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
node.js中的fs.chmodSync方法使用说明
2014/12/18 Javascript
Jquery easyui 实现动态树
2015/11/17 Javascript
js闭包引起的事件注册问题介绍
2016/03/29 Javascript
简单实现jQuery级联菜单
2017/01/09 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
解决vue-cli项目webpack打包后iconfont文件路径的问题
2018/09/01 Javascript
Vue引用Swiper4插件无法重写分页器样式的解决方法
2018/09/27 Javascript
详解VUE Element-UI多级菜单动态渲染的组件
2019/04/25 Javascript
jquery实现轮播图特效
2020/04/12 jQuery
vue实践---vue不依赖外部资源实现简单多语操作
2020/09/21 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
2020/11/12 Javascript
python中matplotlib实现最小二乘法拟合的过程详解
2017/07/11 Python
Java编程迭代地删除文件夹及其下的所有文件实例
2018/02/10 Python
python之pexpect实现自动交互的例子
2019/07/25 Python
python网络编程之多线程同时接受和发送
2019/09/03 Python
Python序列对象与String类型内置方法详解
2019/10/22 Python
Python操作redis和mongoDB的方法
2019/12/19 Python
实现ECharts双Y轴左右刻度线一致的例子
2020/05/16 Python
基于Python第三方插件实现西游记章节标注汉语拼音的方法
2020/05/22 Python
Python基于yaml文件配置logging日志过程解析
2020/06/23 Python
Keras loss函数剖析
2020/07/06 Python
详解Python GUI编程之PyQt5入门到实战
2020/12/10 Python
全网最细 Python 格式化输出用法讲解(推荐)
2021/01/18 Python
python os.listdir()乱码解决方案
2021/01/31 Python
请描述一下”is a”关系和”has a”关系
2015/02/03 面试题
任命书怎么写
2014/06/04 职场文书
“向国旗敬礼”活动策划方案(4篇)
2014/09/27 职场文书
党的群众路线教育实践活动查摆问题及整改措施
2014/10/10 职场文书
班主任自我评价范文
2015/03/11 职场文书
庆元旦主持词
2015/07/06 职场文书
严以用权专题学习研讨会发言材料
2015/11/09 职场文书
python自动化之如何利用allure生成测试报告
2021/05/02 Python
redis缓存存储Session原理机制
2021/11/20 Redis