打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Trie树的php实现
本文原创,转载请注明出处
<?php
/**
 * Trie树
 * 
 * @author iamlaobie@gmail.com
 * @since 2012-08-19
 */
class Trie
{  
    /**
     * 树的存储
     */
    private $_tree = array();

    /**
     * 插入一个新词
     * 
     * @param $word 词
     * @param $data 词附加属性
     */
    public function insert($word, $data = array())
    {
        $cur = & $this->_tree;
        for($i = 0, $len = strlen($word); $i < $len; $i++){
            $ascValue = ord($word[$i]);
            if(!isset($cur[$ascValue])){
                $cur[$ascValue] = array();
            }

            if($i == $len - 1){
                $data['text'] = $word;
                $cur[$ascValue]['$'] = $data;
                break;
            }else{
                $cur = & $cur[$ascValue];
            }
        }
    }
    
    /**
     * 查找词
     */
    public function find($word)
    {
        $cur = & $this->_tree;
        for($i = 0, $len = strlen($word); $i < $len; $i++){
            $ascValue = ord($word[$i]); 
            if(!isset($cur[$ascValue])){
                return null;
            }
            
            if($i == $len - 1){
                if(isset($cur[$ascValue]['$'])){
                    return $cur[$ascValue]['$'];
                }
            }else{
                $cur = $cur[$ascValue];
            }
        }
        return null;
    }

    /**
     * 获取以$word为前缀的词
     * 
     * @param $depth 后缀长度
     */
    public function suffixes($word, $depth = 1)
    {
        $cur = & $this->_tree;
        $words = array();
        for($i = 0, $len = strlen($word); $i < $len; $i++){
            $ascValue = ord($word[$i]);
            if(!isset($cur[$ascValue])){
                return null;
            }

            if($i == $len - 1){
                return $this->traverse($cur, $depth); 
            }else{
                $cur = $cur[$ascValue];
            }
        }
        return null; 
    }

    /**
     * 遍历
     */
    public function traverse($tree = null, $depth = 1, $words = array(), $recuDepth = 0)
    {
        if($tree === null){
            $tree = $this->_tree;
        }

        $recuDepth += 1;
        unset($tree['$']);
         
        //中文utf8编码长度为3
        $realDepth = $depth * 3;
        foreach($tree as $ascValue => $subTree){
            if(isset($subTree['$'])){
                $words[] = $subTree['$'];    
            }
            if(!empty($subTree) && $recuDepth <= $realDepth){
                $words = $this->traverse($subTree, $depth, $words, $recuDepth);
            }
        }
        return $words;
    }

    /**
     * 打印树
     */
    public function tree()
    {
        print_r($this->_tree);
    }
}

//测试
$trie = new Trie();

$trie->insert("中国人", array('a' => 1));
$trie->insert("中国通", array('a' => 1));
$trie->insert("中国人地", array('a' => 1));
$trie->insert("中国人民", array('a' => 1));
$trie->insert("中方通", array('a' => 2));
$trie->insert("abc", array('a' => 2));
$trie->insert("外方", array('a' => 2));

var_dump($trie->suffixes('中国人', 1));

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
2008
AC算法详解
trie树
Trie树
glib库数组GArray介绍
JS之数组的几个牛逼操作~面试高频
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服