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代码质量36计
Sep 05 PHP
新浪SAE云平台下使用codeigniter的数据库配置
Jun 12 PHP
php备份数据库类分享
Apr 14 PHP
php使用标签替换的方式生成静态页面
May 21 PHP
Laravel执行migrate命令提示:No such file or directory的解决方法
Mar 16 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
Oct 18 PHP
Centos 6.5系统下编译安装PHP 7.0.13的方法
Dec 19 PHP
Laravel中任务调度console使用方法小结
May 07 PHP
Docker搭建自己的PHP开发环境
Feb 24 PHP
php微信开发之关注事件
Jun 14 PHP
YII框架学习笔记之命名空间、操作响应与视图操作示例
Apr 30 PHP
PHP实现笛卡尔积算法的实例讲解
Dec 22 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
mysql中存储过程、函数的一些问题
2007/02/14 PHP
基于ubuntu下nginx+php+mysql安装配置的具体操作步骤
2013/04/28 PHP
使用GD库生成带阴影文字的图片
2015/03/27 PHP
PHP常见数组排序方法小结
2018/08/20 PHP
关于viewport,Ext.panel和Ext.form.panel的关系
2009/05/07 Javascript
3Z版基于jquery的图片复选框(asp.net+jquery)
2010/04/12 Javascript
jquery实现多级下拉菜单的实例代码
2013/10/02 Javascript
jQuery获得IE版本不准确webbrowser的解决方法
2014/02/23 Javascript
wap浏览自动跳转到wap页面的js代码
2014/05/17 Javascript
form.submit()不能提交表单的原因分析
2014/10/23 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
2015/05/14 Javascript
vue从使用到源码实现教程详解
2016/09/19 Javascript
js倒计时显示实例
2016/12/11 Javascript
JS绘制微信小程序画布时钟
2016/12/24 Javascript
Bootstrap3 多个模态对话框无法显示的解决方案
2017/02/23 Javascript
Vue.js 动态为img的src赋值方法
2018/03/14 Javascript
js传递数组参数到后台controller的方法
2018/03/29 Javascript
vue elementUI使用tabs与导航栏联动
2019/06/21 Javascript
[44:22]完美世界DOTA2联赛循环赛 FTD vs PXG BO2第一场 11.01
2020/11/02 DOTA
Python实现从脚本里运行scrapy的方法
2015/04/07 Python
flask-socketio实现WebSocket的方法
2018/07/31 Python
Pandas中Series和DataFrame的索引实现
2019/06/27 Python
Python实现TCP通信的示例代码
2019/09/09 Python
详解Python list和numpy array的存储和读取方法
2019/11/06 Python
Python3.6 中的pyinstaller安装和使用教程
2020/03/16 Python
pyautogui自动化控制鼠标和键盘操作的步骤
2020/04/01 Python
Keras load_model 导入错误的解决方式
2020/06/09 Python
matplotlib基础绘图命令之errorbar的使用
2020/08/13 Python
请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
2015/07/16 面试题
中间件分为哪几类
2016/09/18 面试题
本科生学习总结的自我评价
2013/10/02 职场文书
医学护理毕业生自荐信
2013/11/07 职场文书
应届毕业生的自我鉴定
2013/11/13 职场文书
班级道德讲堂实施方案
2014/02/24 职场文书
python基于tkinter制作m3u8视频下载工具
2021/04/24 Python
Python 中数组和数字相乘时的注意事项说明
2021/05/10 Python