我是一个lisp初学者,我正在尝试编写一个为trie定义类并为其读取整个拼字游戏字典的包。该结构充当节点,每个节点都有一个关联列表,用于跟踪源自它的字母(通向其他子集)。在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节点成为一个结构而不是一个类,并得到了类似的结果。我也有一个递归算法来添加字典中的单词,但它同样糟糕。
我一直在为此而努力了几个小时,我有点沮丧......
我试着首先用哈希表实现......我认为a-lists会更有效率。这个实现的要点是,一个单词中的每个字母都应该位于一个单独的子树中,如果该字母的子分支不存在,则只创建一个新的子树。有关终止于某些子项的单词的信息以及子单元下存在多少单词也是目标的一部分(因此,为什么我想通过关联n-trie实例的关联列表来跟踪此信息。) 我同意它不似乎是最有效的方式来存储信息... –
也(next-letters tri)只是访问n-trie类的(下一个字母)属性...所以这不应该是那么大的一个内存问题 –
你的哈希表中每个键的值是多少?它是否是另一个节点?你如何遍历这棵树? –