1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- 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
- 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
- } else {
- child := new(node)
- child.depth = i + 1
- nd.children[char] = child
- nd = child
- }
- }
- nd.end = true
- }
- func (n *node) build() {
- var nodes []*node
- for _, child := range n.children {
- child.fail = n
- nodes = append(nodes, child)
- }
- for len(nodes) > 0 {
- nd := nodes[0]
- nodes = nodes[1:]
- for key, child := range nd.children {
- nodes = append(nodes, child)
- cur := nd
- for cur != nil {
- if cur.fail == nil {
- child.fail = n
- break
- }
- if fail, ok := cur.fail.children[key]; ok {
- child.fail = fail
- break
- }
- cur = cur.fail
- }
- }
- }
- }
- 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 {
- for cur != n {
- cur = cur.fail
- if child, ok = cur.children[chars[i]]; ok {
- cur = child
- break
- }
- }
- if child == nil {
- continue
- }
- }
- for child != n {
- if child.end {
- scopes = append(scopes, scope{
- start: i + 1 - child.depth,
- stop: i + 1,
- })
- }
- child = child.fail
- }
- }
- return scopes
- }
|