• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧
您的位置:首页 > CMS教程 >建站教程 > PHP实现搜索联想功能(基于字典树算法)

PHP实现搜索联想功能(基于字典树算法)

作者:站长图库 字体:[增加 减小] 来源:互联网

站长图库向大家介绍了PHP实现,搜索联想功能,字典树算法等相关知识,希望对您有所帮助

搜索联想功能是各大搜索引擎具备的基础功能,如下图所示,这个功能简化了用户的输入行为,并且能够给用户推荐热门的搜索词,下面我们来讲一下如何用php实现搜索联想的功能。


5eec3f8886e00.jpg

实现原理

搜索联想功能拆解一下由两部分组成

1、给定一个查询词,找出以他为前缀的其他目标查询词

2、对目标查询词进行排序,选出权重高的若干个查询词

本篇中重点讲解一下第一部分的实现,这里使用Trie树,也叫字典树,这个数据结构来解决这个问题。通过Trie树可以很方便快速的找到已该字符串为前缀的目标字符串。

什么是Trie树

Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率往往比哈希表高。

Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

它有3个基本性质:

1、根节点不包含字符,除根节点外每一个节点都只包含一个字符。

2、从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

3、每个节点的所有子节点包含的字符都不相同。

假如我们有如下字符串

hello,hi,today,touch,weak

那么构造出来的Trie树如下图所示

5eec3fc2556ae.jpg

当查询的时候只需要从根开始按字符沿着树进行深度遍历,就可以把已该词为前缀的其他查询词查找出来。

代码实现

用于实现搜索联想功能的核心方法有两个:

1、将查询词的数据集构建成Trie树

2、查找以某个查询词为前缀的所有查询词

第一步:构建Trie树

注意由于一个字符串有中文有英文,所以对每个字符串使用以下代码进行了分割,将字符串转化成了一个字符的数组

$charArray = preg_split('/(?<!^)(?!$)/u', $str);

然后对每个字符串执行addWordToTrieTree方法,这个方法将一个词加入到Trie树中,这里用到了递归的方法

public function buildTrieTree($strList) {    $tree = [];    foreach($strList as $str) {        $charArray = preg_split('/(?<!^)(?!$)/u', $str);         $tree = $this->addWordToTrieTree($charArray, $tree);    }    return $tree;}public function addWordToTrieTree($charArray, $tree) {    if (count($charArray) == 0) {        return [];    }    $char = $charArray[0];    $leftStr = array_slice($charArray, 1);    $tree[$char] = $this->addWordToTrieTree($leftStr, $tree[$char]);    return $tree;}

第二步:查询前缀词

查询前缀词即给定一个字符串,查询树中所有以该串为前缀的字符串,也就是联想的过程。

首先调用findSubTree方法,从Trie中找到该前缀所在的子树,然后调用traverseTree方法,遍历这颗子树,把所有的字符串都提取出来,这里也是用了递归的方法。

public function queryPrefix($prefix) {    $charArray = preg_split('/(?<!^)(?!$)/u', $prefix);    $subTree = $this->findSubTree($charArray, $this->tree);    $words = $this->traverseTree($subTree);    foreach($words as &$word) {        $word = $prefix . $word;    }    return $words;}public function findSubTree($charArray, $tree) {    foreach($charArray as $char) {        if (in_array($char, array_keys($tree))) {            $tree = $tree[$char];        } else {            return [];        }    }    return $tree;}public function traverseTree($tree) {    $words = [];    foreach ($tree as $node => $subTree) {        if (empty($subTree)) {            $words[] = $node;            return $words;        }        $chars = $this->traverseTree($subTree);        foreach($chars as $char) {            $words[] = $node . $char;        }    }    return $words;}

代码与测试结果

完整代码:

<?phpclass TrieTree {    private $tree;    public function __construct($strList) {        $this->tree = $this->buildTrieTree($strList);    }    public function queryPrefix($prefix) {        $charArray = preg_split('/(?<!^)(?!$)/u', $prefix);        $subTree = $this->findSubTree($charArray, $this->tree);        $words = $this->traverseTree($subTree);         foreach($words as &$word) {            $word = $prefix . $word;        }        return $words;    }    public function findSubTree($charArray, $tree) {        foreach($charArray as $char) {            if (in_array($char, array_keys($tree))) {                $tree = $tree[$char];            } else {                return [];            }        }        return $tree;    }    public function traverseTree($tree) {        $words = [];        foreach ($tree as $node => $subTree)
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 用PHP实现的服务端socket具体实例
  • PHP高清晰度无损图片压缩功能的实现代码
  • PHP实现搜索联想功能(基于字典树算法)
  • 教你用PHP实现微信小程序人脸识别刷脸登录功能

相关文章

  • 分享几种用PHP写99乘法表的方式
  • 浅析小程序中如何优雅地进行模块化处理?
  • php中get_object_vars()在数组的实例用法
  • Photoshop设计黑色大气的网页模板
  • 聊聊Node.js中的事件驱动程序和EventEmitter类
  • PHP中什么是URL.session id?他们之间有什么安全隐患?session id的作用?
  • 使用Let's Encrypt(certbot)安装免费SSL证书
  • dedecms调用Discuz!X2.5最新帖子和图片的方法
  • Photoshop制作漂亮糖果文字效果
  • Thinkphp6微信PC端登录和手机端登录逻辑分享

文章分类

  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧

最近更新的内容

    • PhotoShop设计制作梦幻炫彩光斑文字效果教程
    • Linux下查看PHP配置文件php.ini的位置
    • PHP如何使用面向对象魔术方法之__call函数
    • 如何开启WordPress调试模式(报错提示)
    • Vue中如何根据主题获取不同的资源切换图片
    • 关于laravel5.6与thinkphp3.2使用redis共享session的方案
    • 百度蜘蛛是怎样来判断文章质量的?
    • PHP中如何理解foreach遍历二维数组
    • 消除if else, 让你的代码看起来更优雅
    • 帝国cms中常用标签(总结)

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有