थॉमस और कागो के उत्तरों में समाधान कार्यात्मक रूप से सही है। एक मुद्दा जो आपको परेशान कर सकता है यदि आप उनके समाधान का उपयोग करते हैं, यह है कि यदि आप (=)
के बराबर हैं और (==)
के लिए अलग हैं तो आपको अपेक्षा से अधिक टकराव मिलेगा। दरअसल, (=)
के बराबर सभी कुंजी Hashtbl.hash
के लिए समान हैश है, और उसी बाल्टी में समाप्त होती है, जहां उन्हें अलग-अलग माना जाता है (चूंकि आपने (==)
को समानता फ़ंक्शन के रूप में उपयोग करने के लिए कहा था) और विभिन्न बाइंडिंग बनाते हैं। सबसे बुरे मामलों में, हैश-टेबल एक ही जटिलता के साथ एक एसोसिएशन सूची के रूप में व्यवहार करेगा (जिस तरह से, एक और डेटा संरचना है जिसका आप उपयोग कर सकते हैं, और फिर आपको हैश फ़ंक्शन प्रदान करने की चिंता करने की आवश्यकता नहीं होगी)।
यदि आप कभी-कभी मूल्य बदलने की कुंजी स्वीकार कर सकते हैं (और इसलिए हैश-टेबल से पुनर्प्राप्त करना असंभव है, क्योंकि बाइंडिंग गलत बाल्टी में है), तो आप निम्नलिखित निम्न-स्तरीय फ़ंक्शन का उपयोग कर सकते हैं
external address_of_value: 'a -> int = "address_of_value"
के रूप में सी में लागू किया: हैश के रूप में
#include "caml/mlvalues.h"
value address_of_value(value v)
{
return (Val_long(((unsigned long)v)/sizeof(long)));
}
फिर आप का प्रयोग करेंगे:
module H = Hashtbl.Make(struct
type t = foo
let equal = (==)
let hash = address_of_value
end);;
स्रोत
2012-01-23 16:22:34
इस प्रकार की हैश तुलना थोड़ी कम नाजुक है जब आपके उदाहरण में अपरिवर्तनीय मूल्यों के साथ प्रयोग किया जाता है। दस्तावेजों का कहना है कि (==) का परिणाम उस मामले में निर्भर कार्यान्वयन है: [तुलनात्मक ** मॉड्यूल के तहत पारदर्शी मॉड्यूल **] देखें (http://caml.inria.fr/pub/docs/manual-ocaml/libref/ Pervasives.html)। सिद्धांत रूप में संकलक या रनटाइम किसी भी दो बराबर अपरिवर्तनीय मानों को शारीरिक रूप से बराबर होने का कारण बन सकता है। –
@ जेफरीस्कोफिल्ड कंपाइलर या रनटाइम उन मानों का भी कारण बन सकता है जिन्हें आप अलग-अलग होने के लिए शारीरिक रूप से बराबर होने की उम्मीद करेंगे, और यह सैद्धांतिक नहीं है: 'परीक्षण x = let t = Array.make x x x == t में 0 x (0) ;; परीक्षण 1.0; 'गणना' झूठी '। कैमल के लिए बहु-थ्रेड जीसी जो केवल कागज पर मौजूद है, अपरिवर्तनीय मानों को भी डुप्लिकेट कर सकता है। –
धन्यवाद, ये बहुत ही रोचक उदाहरण हैं, हालांकि मुझे लगता है कि ओपी सिक्का के दूसरी तरफ से अधिक चिंतित है। आप अनूठे भौतिक पहचान (ए! = बी) वाले अपरिवर्तनीय मूल्यों पर निर्भर नहीं हो सकते हैं जब तक कि वे बराबर न हों (एक <> बी)। सामान्य समाधान (या, मैंने जो उपयोग किया है) आपके मूल्यों में एक अद्वितीय पहचानकर्ता रखना है। यह निश्चित रूप से हैशिंग के साथ भी मदद करता है। –