雜湊表
模組 Hashtbl
Hashtbl 模組實作了一個有效率且可變的查找表。要建立一個雜湊表,我們可以寫成
# let my_hash = Hashtbl.create 123456;;
val my_hash : ('_weak1, '_weak2) Hashtbl.t = <abstr>
123456 是雜湊表的初始大小。這個初始數字只是你對雜湊表將放入的資料量的最佳猜測。如果你的估計不足,雜湊表可以擴大,所以不用太擔心。my_hash 的型別是
# my_hash;;
- : ('_weak1, '_weak2) Hashtbl.t = <abstr>
'_weak1
和 '_weak2
分別對應到鍵和值的型別。這些槽位中沒有填入具體的型別(例如,int
或 float * string
),因為鍵和值的型別尚未確定。底線表示鍵和資料型別一旦選定,將會被固定。換句話說,你不能有時候使用一個給定的雜湊表以整數作為鍵,然後稍後在同一個雜湊表中以字串作為鍵。
讓我們將一些資料加入 my_hash
。假設我正在開發一個填字遊戲解謎程式,我想找到所有以特定字母開頭的單字。首先,我需要將資料輸入 my_hash
。
請注意,雜湊表會透過就地更新進行修改,因此,與映射不同,每次更改表格時都不會建立另一個雜湊表。因此,程式碼 let my_hash = Hashtbl.add my_hash ...
沒有任何意義。相反地,我們會這樣寫
# Hashtbl.add my_hash "h" "hello";
Hashtbl.add my_hash "h" "hi";
Hashtbl.add my_hash "h" "hug";
Hashtbl.add my_hash "h" "hard";
Hashtbl.add my_hash "w" "wimp";
Hashtbl.add my_hash "w" "world";
Hashtbl.add my_hash "w" "wine";;
- : unit = ()
如果我們想在 my_hash
中找到一個包含 "h"
的元素,我們會這樣寫
# Hashtbl.find my_hash "h";;
- : string = "hard"
注意到它只回傳一個元素嗎?該元素是最後一個以值 "h"
輸入的元素。
我們可能想要的是所有以 "h"
開頭的元素。為此,我們需要找到所有元素。還有比 find_all
更好的名稱嗎?
# Hashtbl.find_all my_hash "h";;
- : string list = ["hard"; "hug"; "hi"; "hello"]
回傳 ["hard"; "hug"; "hi"; "hello"]
。
如果你移除一個鍵,其先前的值將再次變為與該鍵關聯的預設值。
# Hashtbl.remove my_hash "h";;
- : unit = ()
# Hashtbl.find my_hash "h";;
- : string = "hug"
對於上述範例,或者當鍵表示可以被同名區域變數暫時遮蔽的變數時,這種行為很有趣。
在其他情況下,人們可能更喜歡新值來取代先前的值。在這種情況下,可以使用 Hashtbl.replace
# Hashtbl.replace my_hash "t" "try";
Hashtbl.replace my_hash "t" "test";
Hashtbl.find_all my_hash "t";;
- : string list = ["test"]
# Hashtbl.remove my_hash "t";
Hashtbl.find my_hash "t";;
Exception: Not_found.
要找出 my_hash
中是否有字母的項目,我們可以這樣做
# Hashtbl.mem my_hash "h";;
- : bool = true