golang高效Trie树数据结构实现插件库trie的使用
Golang高效Trie树数据结构实现插件库trie的使用
Trie简介
Trie是一种用于极快速前缀/模糊字符串搜索的数据结构和相关算法。
使用示例
创建Trie
t := trie.New()
添加键值
// Add方法可以接收元信息,这些信息可以与键一起存储
// 即你可以存储任何你想与该键关联的信息
t.Add("foobar", 1)
查找键
node, ok := t.Find("foobar")
meta := node.Meta()
// 使用meta.(type)来处理元数据
移除键
t.Remove("foobar")
前缀搜索
t.PrefixSearch("foo")
快速测试有效前缀
t.HasKeysWithPrefix("foo")
模糊搜索
t.FuzzySearch("fb")
完整示例Demo
package main
import (
"fmt"
"github.com/derekparker/trie"
)
func main() {
// 创建新的Trie树
t := trie.New()
// 添加键值对
t.Add("golang", "Go语言")
t.Add("python", "Python语言")
t.Add("java", "Java语言")
t.Add("javascript", "JavaScript语言")
// 查找特定键
if node, ok := t.Find("golang"); ok {
fmt.Println("找到golang:", node.Meta()) // 输出: 找到golang: Go语言
}
// 前缀搜索
fmt.Println("前缀'jav'的搜索结果:", t.PrefixSearch("jav"))
// 输出: 前缀'jav'的搜索结果: [java javascript]
// 模糊搜索
fmt.Println("模糊搜索'pytn'的结果:", t.FuzzySearch("pytn"))
// 输出: 模糊搜索'pytn'的结果: [python]
// 检查前缀是否存在
fmt.Println("是否存在'go'前缀:", t.HasKeysWithPrefix("go"))
// 输出: 是否存在'go'前缀: true
// 移除键
t.Remove("python")
fmt.Println("移除python后前缀'pyt'的搜索结果:", t.PrefixSearch("pyt"))
// 输出: 移除python后前缀'pyt'的搜索结果: []
}
贡献
克隆此仓库并运行测试:
go test
创建一个特性分支,编写你的测试和代码,然后提交拉取请求。
许可证
MIT
更多关于golang高效Trie树数据结构实现插件库trie的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高效Trie树数据结构实现插件库trie的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang高效Trie树实现及使用指南
Trie树(前缀树或字典树)是一种高效的字符串检索数据结构,特别适合实现自动补全、拼写检查、IP路由等功能。下面我将介绍如何在Go中高效实现和使用Trie树。
标准Trie树实现
基础实现代码
package main
import (
"fmt"
)
type TrieNode struct {
children map[rune]*TrieNode
isEnd bool
}
type Trie struct {
root *TrieNode
}
func NewTrie() *Trie {
return &Trie{root: &TrieNode{children: make(map[rune]*TrieNode)}}
}
// Insert 插入一个单词到Trie树中
func (t *Trie) Insert(word string) {
node := t.root
for _, ch := range word {
if _, ok := node.children[ch]; !ok {
node.children[ch] = &TrieNode{children: make(map[rune]*TrieNode)}
}
node = node.children[ch]
}
node.isEnd = true
}
// Search 查找单词是否存在于Trie树中
func (t *Trie) Search(word string) bool {
node := t.root
for _, ch := range word {
if _, ok := node.children[ch]; !ok {
return false
}
node = node.children[ch]
}
return node.isEnd
}
// StartsWith 检查是否有单词以给定前缀开头
func (t *Trie) StartsWith(prefix string) bool {
node := t.root
for _, ch := range prefix {
if _, ok := node.children[ch]; !ok {
return false
}
node = node.children[ch]
}
return true
}
func main() {
trie := NewTrie()
trie.Insert("apple")
fmt.Println(trie.Search("apple")) // true
fmt.Println(trie.Search("app")) // false
fmt.Println(trie.StartsWith("app")) // true
trie.Insert("app")
fmt.Println(trie.Search("app")) // true
}
高效Trie树插件库
对于生产环境,推荐使用成熟的Trie库,如:
使用示例:derekparker/trie
package main
import (
"fmt"
"github.com/derekparker/trie"
)
func main() {
t := trie.New()
// 插入键值对
t.Add("apple", 1)
t.Add("app", 2)
t.Add("application", 3)
t.Add("banana", 4)
// 精确查找
node, ok := t.Find("app")
if ok {
fmt.Println("Found:", node.Meta()) // 输出: 2
}
// 前缀查找
nodes := t.PrefixSearch("app")
for _, n := range nodes {
fmt.Printf("%s: %v\n", n.Key(), n.Meta())
}
// 输出:
// app: 2
// apple: 1
// application: 3
// 删除键
t.Remove("apple")
// 遍历所有键
t.Each(func(key string, value interface{}) bool {
fmt.Println(key, value)
return true // 返回false可提前终止遍历
})
}
使用示例:Workiva的并发安全Trie (ctrie)
package main
import (
"fmt"
"github.com/Workiva/go-datastructures/trie/ctrie"
"time"
)
func main() {
c := ctrie.New(nil)
// 插入
c.Insert([]byte("apple"), 1)
c.Insert([]byte("app"), 2)
// 查找
if val, ok := c.Lookup([]byte("app")); ok {
fmt.Println("Found:", val) // 输出: 2
}
// 并发安全操作
go func() {
c.Insert([]byte("banana"), 3)
}()
go func() {
c.Insert([]byte("orange"), 4)
}()
time.Sleep(100 * time.Millisecond)
// 快照
snapshot := c.Snapshot()
// 遍历
snapshot.Iterator(func(k []byte, v interface{}) bool {
fmt.Println(string(k), v)
return true
})
}
性能优化技巧
- 压缩Trie:合并只有一个子节点的节点,减少内存使用
- 双数组Trie:使用两个数组代替指针,提高缓存命中率
- 并发安全:对于高并发场景,使用并发安全实现
- 内存池:重用节点对象减少GC压力
应用场景
- 自动补全:快速查找前缀匹配的所有单词
- 拼写检查:快速判断单词是否存在
- IP路由:最长前缀匹配
- 敏感词过滤:高效检测文本中的敏感词
选择哪种实现取决于具体需求:标准Trie适合简单场景,derekparker/trie功能丰富,Workiva的ctrie适合高并发环境。
希望这个指南能帮助你在Go项目中高效使用Trie数据结构!