node.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. for i := len(paths); i < len(chars); i++ {
  93. char := chars[i]
  94. child, ok := cur.children[char]
  95. if ok {
  96. cur = child
  97. if cur.end {
  98. longestMatched = cur
  99. }
  100. paths = append(paths, cur)
  101. } else {
  102. if longestMatched != nil {
  103. return 0, longestMatched.depth, nil
  104. }
  105. if n.end {
  106. return 0, n.depth, nil
  107. }
  108. // new path match
  109. var jump *node
  110. // old path pre longest preMatch
  111. preMatch, preStart := findMatch(paths)
  112. icur := cur
  113. for icur.fail != nil {
  114. jump, ok = icur.fail.children[char]
  115. if ok {
  116. break
  117. }
  118. icur = icur.fail
  119. }
  120. switch {
  121. case preMatch != nil && jump != nil:
  122. if jumpStart := i - jump.depth + 1; preStart < jumpStart {
  123. return preStart, preMatch.depth, nil
  124. } else {
  125. return jumpStart, 0, append(paths[jumpStart:], jump)
  126. }
  127. case preMatch != nil && jump == nil:
  128. return preStart, preMatch.depth, nil
  129. case preMatch == nil && jump != nil:
  130. return i - jump.depth + 1, 0, append(paths[i-jump.depth+1:], jump)
  131. case preMatch == nil && jump == nil:
  132. return i + 1, 0, nil
  133. }
  134. }
  135. }
  136. // this longest matched node
  137. if longestMatched != nil {
  138. return 0, longestMatched.depth, nil
  139. }
  140. if n.end {
  141. return 0, n.depth, nil
  142. }
  143. match, start := findMatch(paths)
  144. if match != nil {
  145. return start, match.depth, nil
  146. }
  147. return len(chars), 0, nil
  148. }
  149. func findMatch(path []*node) (*node, int) {
  150. var result *node
  151. var start int
  152. for i := len(path) - 1; i >= 0; i-- {
  153. icur := path[i]
  154. var cur *node
  155. for icur.fail != nil {
  156. if icur.fail.end {
  157. cur = icur.fail
  158. break
  159. }
  160. icur = icur.fail
  161. }
  162. if cur != nil {
  163. if result == nil {
  164. result = cur
  165. start = i - result.depth + 1
  166. } else if curStart := i - cur.depth + 1; curStart < start {
  167. result = cur
  168. start = curStart
  169. }
  170. }
  171. }
  172. return result, start
  173. }