我是一个 lisp 初学者,我正在尝试编写一个包,它为 trie 定义一个类并将整个拼字游戏字典读入其中。该结构充当一个节点,每个节点都有一个关联列表,用于跟踪源自它的字母(导致其他子尝试)。
这是我的课程代码
(DEFCLASS n-trie ()
((word :accessor word
:initform 'nil
:initarg :word)
(word-count :accessor wcount
:initform 0
:initarg :wcount)
(next-letters :accessor next-letters
:initform 'nil
:initarg :next-letters)))
这是我的添加词功能
(defun add-word (string trie) ;;iterative method for looping through string
(let ((s (coerce string 'list))
(tri trie))
(dolist (item s)
(cond
((assoc item (next-letters tri))
(incf (wcount tri))
(setf tri (cdr (assoc item (next-letters tri)))))
(t
(incf (wcount tri))
(setf (next-letters tri) (acons item (make-instance 'n-trie) (next-letters tri)))
(setf tri (cdr (assoc item (next-letters tri)))))))
(setf (word tri) string)))
这是打开我的文件(拼字游戏字典)并读取每一行的函数
(defun read-words (file trie)
(let((str (open file)))
(labels ((rec (tri)
(let ((line (read-line str nil nil)))
(cond
(line (add-word line tri)
(rec tri))
(t (close str)
trie)))))
(rec trie))))
每当我尝试加载整个字典时,都会出现堆栈溢出。拼字游戏词典中有超过 10 万个单词,但在 6000 时失败了……我的内存使用有问题,但我似乎不知道是什么。
我在这些定义中所做的事情在内存方面本质上是昂贵的吗?我尝试使 trie 节点成为结构而不是类,并得到了类似的结果。我也有一个从字典中添加单词的递归算法,但它同样糟糕。
我已经为此苦苦挣扎了几个小时,我有点沮丧......