前缀搜索树的使用例子(PHP实现)

文章背景

根据PM的期望,我们最终需要给出归类好的数据让用户便捷查看。为啥不用MySQL的group by 是因为数据来源是其它系统的ES结果。

前缀树的作用

trie tree 译为前缀树或字典树。因为子孙节点的前缀都一样的关系,我们可以用它做路由、单词联想、归类排序等。

因为需求要为搜索页做同类分组,方便用户查看。因此思路是用 trie tree 分类然后按照子叶的后缀搜索顺序将乱掉的商品数据做排序。(看最后)

预期结果

php 复制代码
$line = [
            [1, 3, 2, 4, 5, 6, 7],
            [2, 3, 2, 4, 5, 6, 7],
            [2, 3, 1, 4, 5],
            [1, 3, 2, 4, 5, 7, 6],
        ];

代码

php 复制代码
public function insert3(array $parts, int $height, &$tree = [])
    {
        if (count($parts) <= $height) {
            $tree['isEnd'] = true;
            return;
        }
        $part  = $parts[$height];
        [$key,$child] = $this->mathChild($tree['children'], $part);
        if ($height == 0 ) {
            $this->warn(json_encode($tree['children']));
        }
        if ( ! $child) {
            $child = $this->newTrie($part);
            $this->insert3($parts, $height + 1, $child);
            $tree['children'][] = $child;
        } else {
            // 下面这一段非常地重要,它决定了同级兄弟成员
            $this->insert3($parts, $height + 1, $tree['children'][$key]);
        }
    }

public function mathChild(array $children, mixed $part)
    {
        foreach ($children as $key => $child) {
            if ($child['part'] == $part) {
                return [
                    $key,
                    $child,
                ];
            }
        }
        return null;
    }
private function newTrie(mixed $part): array
    {
        return [
            'children' => [],
            'isEnd'    => false,
            'part'     => $part,
        ];
    }
    
public function init()
{
    $line = [
            [1, 3, 2, 4, 5, 6, 7],
            [2, 3, 2, 4, 5, 6, 7],
            [2, 3, 1, 4, 5],
            [1, 3, 2, 4, 5, 7, 6],
        ];
    $tree = $this->newTrie('/');
        foreach ($line as $item) {
            $this->insert3($item, 0, $tree);
        }
    echo json_encode($tree, 256);
}

结果Json

ruby 复制代码
{"children":[{"children":[{"children":[{"children":[{"children":[{"children":[{"children":[{"children":[],"isEnd":true,"part":7}],"isEnd":false,"part":6},{"children":[{"children":[],"isEnd":true,"part":6}],"isEnd":false,"part":7}],"isEnd":false,"part":5}],"isEnd":false,"part":4}],"isEnd":false,"part":2}],"isEnd":false,"part":3}],"isEnd":false,"part":1},{"children":[{"children":[{"children":[{"children":[{"children":[{"children":[{"children":[],"isEnd":true,"part":7}],"isEnd":false,"part":6}],"isEnd":false,"part":5}],"isEnd":false,"part":4}],"isEnd":false,"part":2},{"children":[{"children":[{"children":[],"isEnd":true,"part":5}],"isEnd":false,"part":4}],"isEnd":false,"part":1}],"isEnd":false,"part":3}],"isEnd":false,"part":2}],"isEnd":false,"part":"\/"}

需求背景

现状

期望

相关推荐
CSharp精选营11 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
刘马想放假4 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠5 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
两个人的幸福9 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo11 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack11 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
Darling噜啦啦12 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户30745969820712 天前
PHP 扩展——从入门到理解
php
鹏仔先生12 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
小小工匠13 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化