常见的 lisp 哈希表
Common lisp hashtable
任务是像"name phone"一样读取N个字符串并存入。然后用像"name"这样的请求找到存储的数据。
我的代码将名称和数字存储在哈希表中,但之后找不到任何值。使用 maphash 检查存储的值(它显示所有键值对)。
函数一分为二-space 只是实用程序。
(defparameter data (make-hash-table))
(defun split-by-one-space (string) ; to split string: "aaa bbb" -> (aaa bbb)
(loop for i = 0 then (1+ j)
as j = (position #\Space string :start i)
collect (subseq string i j)
while j))
(dotimes (i (read)) ; input data
(let* ((inp (read-line))
(raw (split-by-one-space inp))
(name (string (car raw)))
(phone (cadr raw)))
(format t "Adding: ~W ~W~%" name phone) ; debug
(setf (gethash name data) phone)))
(maphash #'(lambda (k v) (format t "~a => ~a~%" k v)) data) ; this show all stored data
(loop for line = (read-line *standard-input* nil :eof)
until (or (eq line :eof) (eq line nil))
do
(let ((key (gethash line data))) ; it cannot find anything. Why?
(format t "Searching: ~W~%" line) ; debug
(if (null key)
(format t "Not found~%")
(format t "~A=~A~%" (car key) (cdr key)))))
示例输入:
3
sam 99912222
tom 11122222
harry 12299933
sam
edward
harry
除非指定测试函数,否则散列 tables 将使用 eql
来确定 "is this key identical to that key"。
(defvar *s1* "a string")
(defvar *s2* "a string")
(loop for pred in '(eq eql equal equalp)
do (format t "Using ~a, the result is ~a~%"
pred (funcall pred *s1* *s2*)))
这会生成输出:
Using EQ, the result is NIL
Using EQL, the result is NIL
Using EQUAL, the result is T
Using EQUALP, the result is T
在这种情况下,equal
和equalp
的主要区别在于后者不区分大小写,而前者则不区分大小写。要使用另一个测试函数,请使用 :test
关键字和找到的 "standard" 测试函数之一。如果您不需要不区分大小写的匹配项,您只需像这样创建散列 table:(make-hash-table :test #'equal)
.
任务是像"name phone"一样读取N个字符串并存入。然后用像"name"这样的请求找到存储的数据。 我的代码将名称和数字存储在哈希表中,但之后找不到任何值。使用 maphash 检查存储的值(它显示所有键值对)。
函数一分为二-space 只是实用程序。
(defparameter data (make-hash-table))
(defun split-by-one-space (string) ; to split string: "aaa bbb" -> (aaa bbb)
(loop for i = 0 then (1+ j)
as j = (position #\Space string :start i)
collect (subseq string i j)
while j))
(dotimes (i (read)) ; input data
(let* ((inp (read-line))
(raw (split-by-one-space inp))
(name (string (car raw)))
(phone (cadr raw)))
(format t "Adding: ~W ~W~%" name phone) ; debug
(setf (gethash name data) phone)))
(maphash #'(lambda (k v) (format t "~a => ~a~%" k v)) data) ; this show all stored data
(loop for line = (read-line *standard-input* nil :eof)
until (or (eq line :eof) (eq line nil))
do
(let ((key (gethash line data))) ; it cannot find anything. Why?
(format t "Searching: ~W~%" line) ; debug
(if (null key)
(format t "Not found~%")
(format t "~A=~A~%" (car key) (cdr key)))))
示例输入:
3
sam 99912222
tom 11122222
harry 12299933
sam
edward
harry
除非指定测试函数,否则散列 tables 将使用 eql
来确定 "is this key identical to that key"。
(defvar *s1* "a string")
(defvar *s2* "a string")
(loop for pred in '(eq eql equal equalp)
do (format t "Using ~a, the result is ~a~%"
pred (funcall pred *s1* *s2*)))
这会生成输出:
Using EQ, the result is NIL
Using EQL, the result is NIL
Using EQUAL, the result is T
Using EQUALP, the result is T
在这种情况下,equal
和equalp
的主要区别在于后者不区分大小写,而前者则不区分大小写。要使用另一个测试函数,请使用 :test
关键字和找到的 "standard" 测试函数之一。如果您不需要不区分大小写的匹配项,您只需像这样创建散列 table:(make-hash-table :test #'equal)
.