123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- package stringx
- type node struct {
- children map[rune]*node
- fail *node
- depth int
- end bool
- }
- func (n *node) add(word string) {
- chars := []rune(word)
- if len(chars) == 0 {
- return
- }
- nd := n
- var depth int
- for i, char := range chars {
- if nd.children == nil {
- child := new(node)
- child.depth = i + 1
- nd.children = map[rune]*node{char: child}
- nd = child
- } else if child, ok := nd.children[char]; ok {
- nd = child
- depth++
- } else {
- child := new(node)
- child.depth = i + 1
- nd.children[char] = child
- nd = child
- }
- }
- nd.end = true
- }
- func (n *node) build() {
- n.fail = n
- for _, child := range n.children {
- child.fail = n
- n.buildNode(child)
- }
- }
- func (n *node) buildNode(nd *node) {
- if nd.children == nil {
- return
- }
- var fifo []*node
- for key, child := range nd.children {
- fifo = append(fifo, child)
- if fail, ok := nd.fail.children[key]; ok {
- child.fail = fail
- } else {
- child.fail = n
- }
- }
- for _, val := range fifo {
- n.buildNode(val)
- }
- }
- func (n *node) find(chars []rune) []scope {
- var scopes []scope
- size := len(chars)
- cur := n
- for i := 0; i < size; i++ {
- child, ok := cur.children[chars[i]]
- if ok {
- cur = child
- } else if cur == n {
- continue
- } else {
- cur = cur.fail
- if child, ok = cur.children[chars[i]]; !ok {
- continue
- }
- cur = child
- }
- if child.end {
- scopes = append(scopes, scope{
- start: i + 1 - child.depth,
- stop: i + 1,
- })
- }
- if child.fail != n && child.fail.end {
- scopes = append(scopes, scope{
- start: i + 1 - child.fail.depth,
- stop: i + 1,
- })
- }
- }
- return scopes
- }
|