Guest User

documentation for trie

a guest
Jun 19th, 2025
14
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. ;;unoptimized trie
  2. (defstruct (tr-node (:conc-name nil))
  3. ;; conc-name nil means that tr-node is not the leader of this struct
  4. ;; we will not use tr-node-val but rather val directly
  5. val
  6. (children (list)))
  7. (defun tr-lookup (key root)
  8. "go through vector, at the end extract value of root
  9. but before that save the cdr of the current
  10. element of the key vector mapped to the
  11. car of the root's children, as in the child itself,
  12. the cdr in this case being the link to the next node
  13. that the child has, then save that link to the
  14. next recursive section of the tree into the root, in
  15. root trie-lookup search-within from-root
  16. the root's children become the current root"
  17. ;; dovector dotimes+aref
  18. (rtl:dovec (ch key
  19. ;; when iteration terminates normally
  20. ;; we have found the node we were looking for
  21. (val root) ;; run the val command which calls the defstruct
  22. ;;apply that to the root of the tree
  23. ;;this one function is called when the dovec is done
  24. )
  25. #|
  26. (if-it (foo)
  27. (bar it))
  28. (let ((it (foo)))
  29. (if it
  30. (bar it)))
  31. btw this it is saved in a variable called i
  32. (rtl:assoc1 'a '((a . 1)))
  33. 1 (1 bit, #x1, #o1, #b1)
  34. T
  35. |#
  36. (rtl:if-it (rtl:assoc1 ch (children root)) ;;assoc1=(o cdr assoc)
  37. ;; save the cdr of the ch in it
  38. ;; this yeilds nextnode
  39. ;; yeah chilren has a next node
  40. ;; children root is a list of cons cells
  41. ;;((childrenlist. nextnode) (children . nextnode))
  42. ;; moves root to the child node
  43. (setf root rtl:it)
  44. (return))))
  45.  
  46. (defun tr-add (key val root)
  47. (let ((i 0))
  48. (rtl:dovec (ch key)
  49. ;; dont do anything at the end
  50. (rtl:if-it (rtl:assoc1 ch (children root))
  51. ;; save the root children's next link towards the next tr-node
  52. (progn(setf root rtl:it)
  53. ;; increment i if we keep finding a child with next node
  54. ;; or we have have the child in the children's root
  55. ;; i.e. the current child is not of root
  56. (incf i))
  57. (return)))
  58. ;; if we have all children already parented
  59. (if (= i (length key))
  60. ;; something has already being stored at key -
  61. ;; so we signal a continuable error that
  62. ;; gives the user two options: overwrite or abort
  63. (cerror "Assign a new value"
  64. "There was already a value at key: ~A" (val root))
  65. ;; our root already has keys
  66. ;; if it doesn't have keys
  67. ;; iterate with the keys that are not
  68. ;; found in
  69. ;; ((child1 . next)(child2. next))
  70. (rtl:dovec (ch (rtl:slice key i))
  71. ;; iterate over the children that are not of root
  72. ;; make a new child which is a struct with val and children
  73. ;; this brcomes a new root
  74. (let ((child (make-tr-node)))
  75. ;; push the current childless element onto the children of root
  76. (push (cons ch child) (children root))
  77. (setf root child))))
  78. ;; root becomes the strucure with val and children
  79. (setf (val root) val)))
  80. CL-USER> (defparameter *trie* (make-tr-node))
  81. *TRIE*
  82. CL-USER> *trie*
  83. #S(TR-NODE :VAL NIL :CHILDREN NIL)
  84. For the sake of brevity, we won’t define a special print-function for our trie and will
  85. use a default one. In a real setting, though, it is highly advisable:
  86. CL-USER> (tr-lookup "word" *trie*)
  87. NIL
  88. CL-USER> (tr-add "word" 42 *trie*)
  89. 42
  90. CL-USER> *trie*
  91. #S(TR-NODE
  92. :VAL NIL
  93. :CHILDREN
  94. ((#\w
  95. . #S(TR-NODE
  96. :VAL NIL
  97. :CHILDREN
  98. ((#\o
  99. . #S(TR-NODE
  100. :VAL NIL
  101. :CHILDREN
  102. ((#\r
  103. . #S(TR-NODE
  104. :VAL NIL
  105. :CHILDREN
  106. ((#\d
  107. . #S(TR-NODE
  108. :VAL 42
  109. :CHILDREN NIL)))))))))))))
  110. CL-USER> (tr-lookup "word" *trie*)
  111. 42
  112. CL-USER> (tr-add "word" :foo *trie*)
  113. There was already a value at key: 42
  114. [Condition of type SIMPLE-ERROR]
  115. Restarts:
  116. 0: [CONTINUE] Assign a new value
  117. 1: [RETRY] Retry SLIME REPL evaluation request.
  118. 2: [*ABORT] Return to SLIME's top level.
  119. 3: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING>)
  120. Backtrace:
  121. 0: (TR-ADD "word" :FOO #S(TR-NODE :VAL 42 :CHILDREN NIL))
  122. 1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (TR-ADD "word" :FOO *TRIE*) #<NULL-
  123. LEXENV>)
  124. 2: (EVAL (TR-ADD "word" :FOO *TRIE*))
  125. --more--
  126. ;;; Take the restart 0
  127. :FOO
  128. CL-USER> (tr-add "we" :baz *trie*)
  129. :BAZ
  130. CL-USER> *trie*
  131.  
  132. #S(TR-NODE
  133. :VAL NIL
  134. :CHILDREN
  135. ((#\w
  136. . #S(TR-NODE
  137. :VAL NIL
  138. :CHILDREN
  139. ((#\e . #S(TR-NODE
  140. :VAL :BAZ
  141. :CHILDREN NIL))
  142. (#\o . #S(TR-NODE
  143. :VAL NIL
  144. :CHILDREN
  145. ((#\r
  146. . #S(TR-NODE
  147. :VAL NIL
  148. :CHILDREN
  149. ((#\k
  150. . #S(TR-NODE
  151. :VAL :BAR
  152. :CHILDREN NIL))
  153. (#\d
  154. . #S(TR-NODE
  155. :VAL :FOO
  156. :CHILDREN NIL)))))))))))))
Advertisement
Add Comment
Please, Sign In to add comment