我想知道这段代码有什么问题.Assume *语料库是一个单词列表(“at”“the”...),这段代码试图将它们保存在哈希表中(字时间重复) -word)
(defparameter h (make-hash-table))
(defparameter ex 0)
(loop for x in *corpus
do ((setf ex 0)
(loop for y being the hash-keys of h
if (equal x y) do ((incf (gethash y h)) (setf ex 1)))
if (eql ex 0)
do (setf (gethash x h) 1)))
如果单词在哈希表中只增加1,则添加一对新词。
答案 0 :(得分:4)
你想迭代一个单词集;对于每个单词 w ,如果 w 在某个散列中映射到整数 n ,则需要递增该数字以便 w 映射到 n + 1 ;否则,您要将该单词映射为1。
基本上,你想这样做:
(defun increment-corpus (corpus hash)
(map nil
(lambda (word)
(incf (gethash word hash 0)))
corpus))
我正在使用MAP
,以便我可以迭代任何单词序列,而不仅仅是列表。
MAP
的结果类型为NIL
,因为我不关心结果,我只是想制造副作用。
应用的函数只会增加绑定到word
的当前值。请注意,GETHASH
提供了一个默认表单,以便在没有值绑定到给定键的情况下进行评估。在这里,我只需要设置零,以便增量适用于所有情况。我起初并没有读过它,但来自Terje D.的this comment已经说过了。
(defparameter *hash* (make-hash-table :test #'equal))
(defun test (&rest words)
(increment-corpus words *hash*)
(maphash (lambda (&rest entry) (print entry)) *hash*))
哈希最初是空的。
> (test "a" "b" "c" "d")
("a" 1)
("b" 1)
("c" 1)
("d" 1)
> (test "a")
("a" 2)
("b" 1)
("c" 1)
("d" 1)
> (test "a" "b" "c" "x")
("a" 3)
("b" 2)
("c" 2)
("d" 1)
("x" 1)
答案 1 :(得分:3)
CL中的块看起来像这样:
(progn
expression1
expression2
...
expressionn); the result of the form is result of expressionn
这可以用于需要一个表达式的地方,因为块是一个表达式。在循环do
之后可以跟一个或多个复合形式(函数调用,宏调用,特殊形式......):
(loop :for element :in list
:do expression1
expression2
expression3)