123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- package main
- import "sync"
- // 多叉树
- type (
- //MultiTreeNode 多叉树节点
- MultiTreeNode struct {
- Key rune
- End bool
- Children map[rune]*MultiTreeNode
- }
- //MultiTree 多叉树
- MultiTree struct {
- Root *MultiTreeNode
- Lock sync.Mutex // 添加互斥锁
- }
- //结果
- Result struct {
- Data string
- Start, End int
- }
- )
- func NewMultiTree() *MultiTree {
- return &MultiTree{
- Root: &MultiTreeNode{
- Children: make(map[rune]*MultiTreeNode),
- },
- }
- }
- func (mt *MultiTree) Add(segment string) {
- mt.Lock.Lock()
- defer mt.Lock.Unlock()
- path := []rune(segment)
- node := mt.Root
- pathLen := len(path)
- for index, t := range path {
- end := index == pathLen-1
- if v, ok := node.Children[t]; ok {
- node = v
- if end { //后加入的词(可能是老词的子集),需要修正属性
- node.End = end
- }
- } else {
- leafNode := &MultiTreeNode{
- Key: t,
- Children: make(map[rune]*MultiTreeNode),
- }
- if end { //是结束节点
- leafNode.End = true
- }
- node.Children[t] = leafNode
- node = leafNode
- }
- }
- }
- // Match 匹配 / 查找
- func (mt *MultiTree) Match(segment string, maximum bool) []*Result {
- mt.Lock.Lock()
- defer mt.Lock.Unlock()
- var wordNode *MultiTreeNode
- node := mt.Root
- var ok bool
- path := []rune(segment)
- ret := make([]*Result, 0, 0)
- pos := 0
- //找第一层
- for pos < len(path) {
- if wordNode, ok = node.Children[path[pos]]; !ok {
- pos += 1
- continue
- }
- skipStep := 1
- for w := pos + 1; w < len(path); w++ {
- if wordNode, ok = wordNode.Children[path[w]]; !ok {
- break
- }
- if wordNode.End && !maximum {
- return []*Result{
- &Result{
- Data: string(path[pos : w+1]), Start: pos, End: w + 1},
- }
- } else if wordNode.End {
- ret = append(ret, &Result{
- Data: string(path[pos : w+1]), Start: pos, End: w + 1})
- skipStep = w - pos
- }
- }
- pos += skipStep
- }
- return ret
- }
|