方法
package xxxx
const defaultMask = '*'
type (
TrieOption func(trie *trieNode)
Trie interface {
Filter(text string) (string, []string, bool)
FindKeywords(text string) []string
}
trieNode struct {
node
mask rune
}
scope struct {
start int
stop int
}
)
func NewTrie(words []string, opts ...TrieOption) Trie {
n := new(trieNode)
for _, opt := range opts {
opt(n)
}
if n.mask == 0 {
n.mask = defaultMask
}
for _, word := range words {
n.add(word)
}
n.build()
return n
}
func (n *trieNode) Filter(text string) (sentence string, keywords []string, found bool) {
chars := []rune(text)
if len(chars) == 0 {
return text, nil, false
}
scopes := n.find(chars)
keywords = n.collectKeywords(chars, scopes)
for _, match := range scopes {
n.replaceWithAsterisk(chars, match.start, match.stop)
}
return string(chars), keywords, len(keywords) > 0
}
func (n *trieNode) FindKeywords(text string) []string {
chars := []rune(text)
if len(chars) == 0 {
return nil
}
scopes := n.find(chars)
return n.collectKeywords(chars, scopes)
}
func (n *trieNode) collectKeywords(chars []rune, scopes []scope) []string {
set := make(map[string]struct{})
for _, v := range scopes {
set[string(chars[v.start:v.stop])] = struct{}{}
}
var i int
keywords := make([]string, len(set))
for k := range set {
keywords[i] = k
i++
}
return keywords
}
func (n *trieNode) replaceWithAsterisk(chars []rune, start, stop int) {
for i := start; i < stop; i++ {
chars[i] = n.mask
}
}
func WithMask(mask rune) TrieOption {
return func(n *trieNode) {
n.mask = mask
}
}
使用
trie := NewTrie([]string{
"bc",
"cd",
})
output, keywords, found := trie.Filter("abcd")
fmt.Println(output)
fmt.Println(keywords)
fmt.Println(found)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义