Lisp - 雜湊表



雜湊表資料結構表示基於鍵的雜湊碼組織的鍵值對集合。它使用鍵來訪問集合中的元素。

當您需要使用鍵訪問元素,並且可以識別有用的鍵值時,可以使用雜湊表。雜湊表中的每個專案都具有鍵值對。鍵用於訪問集合中的專案。

在LISP中建立雜湊表

在 Common LISP 中,雜湊表是一種通用的集合。您可以使用任意物件作為鍵或索引。

當您將值儲存在雜湊表中時,您會建立一個鍵值對,並將其儲存在該鍵下。稍後,您可以使用相同的鍵從雜湊表中檢索該值。每個鍵只對映到一個值,儘管您可以將新值儲存在同一個鍵下。

在 LISP 中,雜湊表可以根據鍵的比較方式分為三種類型:eq、eql 或 equal。如果雜湊表對 LISP 物件進行雜湊,則鍵將使用 eq 或 eql 進行比較。如果雜湊表對樹結構進行雜湊,則將使用 equal 進行比較。

make-hash-table 函式用於建立雜湊表。此函式的語法如下:

make-hash-table &key :test :size :rehash-size :rehash-threshold

其中:

  • key 引數提供鍵。

  • :test 引數確定如何比較鍵 - 它應該具有三個值之一:#'eq、#'eql 或 #'equal,或三個符號 eq、eql 或 equal 之一。如果未指定,則假定為 eql。

  • :size 引數設定雜湊表的初始大小。這應該是一個大於零的整數。

  • :rehash-size 引數指定當雜湊表變滿時增加雜湊表大小的幅度。這可以是一個大於零的整數(要新增的條目數),也可以是一個大於 1 的浮點數(新大小與舊大小的比率)。此引數的預設值取決於實現。

  • :rehash-threshold 引數指定雜湊表在必須增長之前可以達到多滿。這可以是一個大於零且小於 :rehash-size 的整數(在這種情況下,每當表增長時都會對其進行縮放),也可以是一個介於零和 1 之間的浮點數。此引數的預設值取決於實現。

您也可以不帶任何引數呼叫 make-hash-table 函式。

從雜湊表中檢索專案和向雜湊表中新增專案

gethash 函式透過搜尋其鍵來從雜湊表中檢索專案。如果找不到鍵,則返回 nil。

它的語法如下:

gethash key hash-table &optional default

其中:

  • key:是關聯的鍵

  • hash-table:是要搜尋的雜湊表

  • default:如果未找到條目,則返回的值為 nil,如果未指定則為 nil。

gethash 函式實際上返回兩個值,第二個值是一個謂詞值,如果找到條目則為真,如果未找到條目則為假。

要向雜湊表新增專案,您可以使用setf 函式以及gethash 函式。

示例

建立一個名為 main.lisp 的新原始碼檔案,並在其中鍵入以下程式碼。

main.lisp

; create a hashtable
(setq empList (make-hash-table)) 
(setf (gethash '001 empList) '(Charlie Brown))
(setf (gethash '002 empList) '(Freddie Seal)) 
; print the value for 001 from hashtable
(write (gethash '001 empList))
; terminate printing 
(terpri)
; print the value for 002 from hashtable
(write (gethash '002 empList))  

輸出

執行程式碼時,它返回以下結果:

(CHARLIE BROWN)
(FREDDIE SEAL)

刪除條目

remhash 函式刪除雜湊表中特定鍵的任何條目。這是一個謂詞,如果存在條目則為真,如果不存在條目則為假。

此函式的語法如下:

remhash key hash-table

示例

更新名為 main.lisp 的原始碼檔案,並在其中鍵入以下程式碼。

main.lisp

; create a hashtable
(setq empList (make-hash-table)) 
(setf (gethash '001 empList) '(Charlie Brown))
(setf (gethash '002 empList) '(Freddie Seal)) 
(setf (gethash '003 empList) '(Mark Mongoose)) 

; print the hash for 001 from hashtable
(write (gethash '001 empList))
; terminate printing  
(terpri)
; print the hash for 002 from hashtable
(write (gethash '002 empList))
; terminate printing 
(terpri)
; print the hash for 003 from hashtable
(write (gethash '003 empList))
; remove hash value
(remhash '003 empList)
; terminate printing 
(terpri)
; print the hash for 001 from hashtable
(write (gethash '003 empList))  

輸出

執行程式碼時,它返回以下結果:

(CHARLIE BROWN)
(FREDDIE SEAL)
(MARK MONGOOSE)
NIL

maphash 函式

maphash 函式允許您將指定函式應用於雜湊表上的每個鍵值對。

它接受兩個引數 - 函式和雜湊表,併為雜湊表中的每個鍵值對呼叫一次函式。

示例

更新名為 main.lisp 的原始碼檔案,並在其中鍵入以下程式碼。

main.lisp

; create a hashtable
(setq empList (make-hash-table)) 
(setf (gethash '001 empList) '(Charlie Brown))
(setf (gethash '002 empList) '(Freddie Seal)) 
(setf (gethash '003 empList) '(Mark Mongoose)) 

; map hash on hashtable
(maphash #'(lambda (k v) (format t "~a => ~a~%" k v)) empList)

輸出

執行程式碼時,它返回以下結果:

3 => (MARK MONGOOSE)
2 => (FREDDIE SEAL)
1 => (CHARLIE BROWN)
廣告