2016-08-04 54 views
2

任務是讀取類似「名稱電話」的N字符串並存儲。然後查找存儲的數據,請求中包含「name」。 我的代碼將名稱和數字存儲在散列表中,但沒有找到任何值。存儲的值使用maphash進行檢查(它顯示所有對鍵值)。通用lisp散列表

函數split-by-one-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 
+1

請參閱[在Common Lisp中使用字符串對象作爲散列鍵](http://stackoverflow.com/q/1409069/5747548) – jkiiski

回答

4

除非你指定一個測試功能,哈希表將使用eql確定「這是關鍵完全相同關鍵」。

(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 

在這種情況下,equalequalp之間的主要區別是,後者是不區分大小寫的,而前者是沒有的。要使用其他測試功能,請使用:test關鍵字和找到的「標準」測試功能之一。如果你不需要區分大小寫的匹配,你可以簡單地創建你的哈希表:(make-hash-table :test #'equal)

+1

@coredump Bah,我希望「塊引用」能夠保留行結尾和愚蠢地沒有檢查。感謝編輯。 – Vatine