數據結構-PHP 字典樹(Trie)的實現

​這篇文章介紹一下字典樹的實現原理,又稱單詞查找樹Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計,排序和保存大量的字符串(但不只限於字符串),因此常常被搜索引擎系統用於文本詞頻統計。它的優勢是:利用字符串的公共前綴來減小查詢時間,最大限度地減小無謂的字符串比較,查詢效率比哈希樹高。php

1.字典樹(Trie)示意圖

2.節點定義

class Node{
  public $isWord;
  public $value;//能夠存儲表示其餘信息
  public $next; //這是一顆 Map 樹,指向其餘 25 個字母
  public function __construct(){
      $this->next = new BinarySearchTreeMap();
  }
}

3.Trie 字典樹類定義

以下定義了一個字典樹(Trie),其中add() 方法能夠向 字典樹 中添加單詞,contains() 能夠查詢 字典樹(Trie) 中是否包含某個單詞,isPrefix() 方法能夠判斷字典樹上是否有指定字符串前綴的單詞:node

<?php
require $root . "/Map/BinarySearchTreeMap.php";
/**
 * 字典樹
 * Class Trie
 */
class Trie
{
    private $root = null;
    private $size;
    public function __construct() {
        $this->root = new TrieNode();
    }
    /**
     * 向字典樹中添加
     * @param string $word向字段樹中添加元素
     */
    public function add(string $word, $value) {
        $node = $this->root;
        for ($i = 0; $i < strlen($word); $i++) {
            $c = $word[$i];
            if ($node->next->get($c) == null) {
                $node->next->add($c, new TrieNode($value));
            }
            $node = $node->next->get($c);
        }
        if (!$node->isWord) {
            $node->isWord = true;
            $this->size++;
        }
    }
    /**
     * 查看單詞 word 是否存在 Trie 樹中
     * @param $word
     */
    public function contains($word) {
        $node = $this->root;
        for ($i = 0; $i < strlen($word); $i++) {
            $c = $word[$i];
            if ($node->next->get($c) == null) {
                return false;
            }
            $node = $node->next->get($c);
        }
        if ($node->isWord) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * 獲取字段樹節點信息
     * @param $word
     */
    public function get($word) {
        $node = $this->root;
        for ($i = 0; $i < strlen($word); $i++) {
            $c = $word[$i];
            if ($node->next->get($c) == null) {
                return null;
            }
            $node = $node->next->get($c);
        }
        return $node->value;
    }
    /**
     * 判斷某個字符串是否爲單詞前綴
     * @param string $prefix
     * @return bool
     */
    public function isPrefix(string $prefix) {
        $node = $this->root;
        for ($i = 0; $i < strlen($prefix); $i++) {
            $c = $prefix[$i];
            if ($node->next->get($c) == null) {
                return false;
            }
            $node = $node->next->get($c);
        }
        return false;
    }
    public function getSize() {
        return $this->size;
    }
}
class TrieNode
{
    public $isWord = false;
    public $next;
    public $value = null;
    public function __construct($value = null) {
        $this->value = $value;
        $this->next = new BinarySearchTreeMap();
    }
}

4.輸出演示

<?php
require 'Trie.php';
$trie = new Trie();
$trie->add('qsx',123);
$trie->add('dog',456);
$trie->add('cat',789);
$trie->add('else',111);
$trie->add('good',111);
var_dump($trie->contains('qsx'));
var_dump($trie->contains('dog'));
var_dump($trie->contains('aaaa'));
var_dump($trie->contains('ddd'));

var_dump($trie->get('qsx'));
var_dump($trie->get('cat'));
var_dump($trie->get('dog'));
var_dump($trie->get('good'));

var_dump($trie->isPrefix('go'));
var_dump($trie->isPrefix('goo'));
var_dump($trie->isPrefix('goop'));

代碼倉庫 :https://gitee.com/love-for-po...git

掃碼關注愛因詩賢oop

相關文章
相關標籤/搜索