写在前面:本文侧重诠释对算法的思考记录过程,忽略其他诸如代码简洁、字符编码等细节问题。
<?php
$trie = new Trie();
$strs = ["释雨", "Summer", "Rain", "释雨的博客", "Blog"];
foreach ($strs as $str) {
$trie->insert($str);
}
var_dump($trie::$ptr);
if ($trie->select("释雨的笔记本")) {
print '包含这个字符串';
} else {
print '不包含这个字符串';
}
//Trie树,也叫前缀树或字典树,是利用字符串之间的公共前缀,将重复的前缀合并在一起,
//组成的一个树形结构,专门用于处理字符串匹配,
//用来解决在一组字符串集合中快速查找某个字符串的问题。
//通常,我们可以通过 Trie 树来构建敏感词或关键词匹配系统。
class TrieNode {
public $data;
public $children = [];
public $isEnd;
public function __construct($data) {
$this->data = $data;
}
}
class Trie {
private static $root;
public static $ptr;
public function __construct() {
self::$root = new TrieNode('/');
self::$ptr = self::$root;
}
// 往Trie树中插入一个字符串,
//时间复杂度:O(n) n为插入的字符串的长度
public function insert($str) {
for ($i=0; $i<mb_strlen($str); $i++) {
$index = $data = $str[$i];
if (!isset(self::$ptr->children[$index])) {
$trieNode = new TrieNode($data);
self::$ptr->children[$index] = $trieNode;
self::$ptr = self::$ptr->children[$index];
}
}
self::$ptr->isEnd = TRUE;
self::$ptr = self::$root;
}
//查找一个字符串是否存在于Trie树中
//时间复杂度:O(k) k为要查找的字符串的长度
public function select($str) {
for ($i=0; $i<mb_strlen($str); $i++) {
$index = $str[$i];
if (empty(self::$ptr->children[$index])) {
return FALSE;
}
self::$ptr = self::$ptr->children[$index];
}
if (!self::$ptr->isEnd) {
return FALSE;
}
return TRUE;
}
}
参考来源:https://xueyuanjun.com/books/data-structure-and-algorithms