node.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package stringx
  2. type node struct {
  3. children map[rune]*node
  4. fail *node
  5. depth int
  6. end bool
  7. }
  8. func (n *node) add(word string) {
  9. chars := []rune(word)
  10. if len(chars) == 0 {
  11. return
  12. }
  13. nd := n
  14. for i, char := range chars {
  15. if nd.children == nil {
  16. child := new(node)
  17. child.depth = i + 1
  18. nd.children = map[rune]*node{char: child}
  19. nd = child
  20. } else if child, ok := nd.children[char]; ok {
  21. nd = child
  22. } else {
  23. child := new(node)
  24. child.depth = i + 1
  25. nd.children[char] = child
  26. nd = child
  27. }
  28. }
  29. nd.end = true
  30. }
  31. func (n *node) build() {
  32. var nodes []*node
  33. for _, child := range n.children {
  34. child.fail = n
  35. nodes = append(nodes, child)
  36. }
  37. for len(nodes) > 0 {
  38. nd := nodes[0]
  39. nodes = nodes[1:]
  40. for key, child := range nd.children {
  41. nodes = append(nodes, child)
  42. cur := nd
  43. for cur != nil {
  44. if cur.fail == nil {
  45. child.fail = n
  46. break
  47. }
  48. if fail, ok := cur.fail.children[key]; ok {
  49. child.fail = fail
  50. break
  51. }
  52. cur = cur.fail
  53. }
  54. }
  55. }
  56. }
  57. func (n *node) find(chars []rune) []scope {
  58. var scopes []scope
  59. size := len(chars)
  60. cur := n
  61. for i := 0; i < size; i++ {
  62. child, ok := cur.children[chars[i]]
  63. if ok {
  64. cur = child
  65. } else {
  66. for cur != n {
  67. cur = cur.fail
  68. if child, ok = cur.children[chars[i]]; ok {
  69. cur = child
  70. break
  71. }
  72. }
  73. if child == nil {
  74. continue
  75. }
  76. }
  77. for child != n {
  78. if child.end {
  79. scopes = append(scopes, scope{
  80. start: i + 1 - child.depth,
  81. stop: i + 1,
  82. })
  83. }
  84. child = child.fail
  85. }
  86. }
  87. return scopes
  88. }
  89. func (n *node) longestMatch(chars []rune, paths []*node) (uselessLen, matchLen int, nextPaths []*node) {
  90. cur := n
  91. var longestMatched *node
  92. findMatch := func(path []*node) (*node, int) {
  93. var (
  94. result *node
  95. start int
  96. )
  97. for i := len(path) - 1; i >= 0; i-- {
  98. icur := path[i]
  99. var cur *node
  100. for icur.fail != nil {
  101. if icur.fail.end {
  102. cur = icur.fail
  103. break
  104. }
  105. icur = icur.fail
  106. }
  107. if cur != nil {
  108. if result == nil {
  109. result = cur
  110. start = i - result.depth + 1
  111. } else if curStart := i - cur.depth + 1; curStart < start {
  112. result = cur
  113. start = curStart
  114. }
  115. }
  116. }
  117. return result, start
  118. }
  119. for i := len(paths); i < len(chars); i++ {
  120. char := chars[i]
  121. child, ok := cur.children[char]
  122. if ok {
  123. cur = child
  124. if cur.end {
  125. longestMatched = cur
  126. }
  127. paths = append(paths, cur)
  128. } else {
  129. if longestMatched != nil {
  130. return 0, longestMatched.depth, nil
  131. }
  132. if n.end {
  133. return 0, n.depth, nil
  134. }
  135. // old path pre longest preMatch
  136. preMatch, preStart := findMatch(paths)
  137. // new path match
  138. var jump *node
  139. icur := cur
  140. for icur.fail != nil {
  141. jump, ok = icur.fail.children[char]
  142. if ok {
  143. break
  144. }
  145. icur = icur.fail
  146. }
  147. switch {
  148. case preMatch != nil && jump != nil:
  149. if jumpStart := i - jump.depth + 1; preStart < jumpStart {
  150. return preStart, preMatch.depth, nil
  151. } else {
  152. return jumpStart, 0, append(paths[jumpStart:], jump)
  153. }
  154. case preMatch != nil && jump == nil:
  155. return preStart, preMatch.depth, nil
  156. case preMatch == nil && jump != nil:
  157. return i - jump.depth + 1, 0, append(paths[i-jump.depth+1:], jump)
  158. case preMatch == nil && jump == nil:
  159. return i + 1, 0, nil
  160. }
  161. }
  162. }
  163. // this longest matched node
  164. if longestMatched != nil {
  165. return 0, longestMatched.depth, nil
  166. }
  167. if n.end {
  168. return 0, n.depth, nil
  169. }
  170. match, start := findMatch(paths)
  171. if match != nil {
  172. return start, match.depth, nil
  173. }
  174. return len(chars), 0, nil
  175. }