Giải pháp trong câu trả lời của Thomas và cago là chính xác về mặt chức năng. Một vấn đề có thể gây rắc rối cho bạn nếu bạn sử dụng giải pháp của họ như là bạn sẽ nhận được nhiều va chạm hơn dự kiến nếu bạn băm nhiều khóa bằng nhau cho (=)
và khác nhau cho (==)
. Thật vậy, tất cả các khóa bằng nhau cho (=)
có cùng giá trị băm cho Hashtbl.hash
và kết thúc trong cùng một nhóm, nơi chúng được nhận dạng là khác nhau (vì bạn đã yêu cầu (==)
để sử dụng làm hàm bình đẳng) và tạo các ràng buộc khác nhau. Trong trường hợp xấu nhất, bảng băm sẽ hoạt động với độ phức tạp tương tự như danh sách liên kết (mà, bằng cách này, là một cấu trúc dữ liệu khác mà bạn có thể sử dụng, và sau đó bạn sẽ không phải lo lắng về việc cung cấp hàm băm).
Nếu bạn có thể chấp nhận khóa của giá trị thay đổi đôi khi (và do đó giá trị không thể truy xuất từ bảng băm, do ràng buộc trong nhóm không đúng), bạn có thể sử dụng hàm mức thấp sau như băm:
external address_of_value: 'a -> int = "address_of_value"
thực hiện trong C như:
#include "caml/mlvalues.h"
value address_of_value(value v)
{
return (Val_long(((unsigned long)v)/sizeof(long)));
}
sau đó bạn sẽ sử dụng:
module H = Hashtbl.Make(struct
type t = foo
let equal = (==)
let hash = address_of_value
end);;
Nguồn
2012-01-23 16:22:34
Loại so sánh băm này hơi mỏng manh khi được sử dụng với các giá trị bất biến, như trong ví dụ của bạn. Các tài liệu cho biết kết quả của (==) phụ thuộc vào việc triển khai thực hiện trong trường hợp đó: xem [Mô-đun Pervasives dưới ** So sánh **] (http://caml.inria.fr/pub/docs/manual-ocaml/libref/ Pervasives.html). Về lý thuyết trình biên dịch hoặc thời gian chạy có thể gây ra bất kỳ hai giá trị bất biến bằng nhau để có thể chất bằng nhau nếu họ muốn. –
@JeffreyScofield Trình biên dịch hoặc thời gian chạy cũng có thể gây ra các giá trị mà bạn mong đợi sẽ khác nhau về mặt vật lý, và đó không phải là lý thuyết: 'let test x = let t = Array.make 1 x in x == t. (0) ;; kiểm tra 1.0 ;; 'tính' sai'. GC đa luồng cho Caml chỉ tồn tại trên giấy cũng có thể nhân đôi giá trị bất biến. –
Cảm ơn, đây là những ví dụ rất thú vị, mặc dù tôi nghĩ OP quan tâm hơn đến phía bên kia của đồng xu. Bạn không thể phụ thuộc vào các giá trị bất biến có các định danh vật lý duy nhất (a! = B) trừ khi chúng không bằng nhau (a <> b). Các giải pháp thông thường (hoặc, một trong những tôi đã sử dụng) là để giữ một định danh duy nhất trong các giá trị của bạn. Điều này cũng giúp với băm, tất nhiên. –