हैश-सेट बदलने योग्य, बिना क्रम वाले संग्रह होते हैं जो हर वैल्यू को अधिकतम एक बार संग्रहीत करते हैं। ढूँढना, डालना और हटाना, तीनों औसतन O(1) समय लेते हैं। ये hash-sets में रहते हैं और sets प्रोटोकॉल को लागू करते हैं।
HS{ "NS-1024" "WB-203" } .
! => HS{ "NS-1024" "WB-203" }
HS{ } खाली लिटरल है। Factor के बाकी लिटरल की तरह यह भी एक साझा ऑब्जेक्ट है। सोर्स में HS{ } का हर रेफरेंस उसी सेट की ओर इशारा करता है। HS{ } clone हर कॉल पर एक नई, स्वतंत्र कॉपी देता है।
>hash-set ( seq -- set ) ! build a fresh set from a sequence
जब आपके पास पहले से किसी सीक्वेंस में वैल्यू हों, तो >hash-set उन्हें एक ही चरण में बदल देता है और दोहराव हटा देता है।
USING: hash-sets prettyprint ;
{ "NS-1024" "WB-203" "NS-1024" } >hash-set .
! => HS{ "NS-1024" "WB-203" }
adjoin ( elt set -- ) ! insert in place; no-op if already present
adjoin-all ( seq set -- ) ! insert every element of seq in place
delete ( elt set -- ) ! remove in place; no-op if absent
तीनों सेट को मौके पर ही बदल देते हैं; इनमें से कोई भी स्टैक पर कुछ नहीं लौटाता।
USING: hash-sets kernel sets ;
HS{ } clone
"NS-1024" over adjoin
"WB-203" over adjoin
"NS-1024" over adjoin ! duplicate — no effect
. ! => HS{ "NS-1024" "WB-203" }
adjoin-all सामूहिक रूप है: यह किसी सीक्वेंस का हर एलिमेंट जोड़ता है और दोहराव को उसी तरह छोड़ देता है जैसे adjoin एक-एक करके छोड़ता है।
USING: hash-sets kernel sets ;
HS{ "NS-1024" } clone
{ "WB-203" "NS-1024" "QR-7" } over adjoin-all
. ! => HS{ "QR-7" "NS-1024" "WB-203" } (order not guaranteed)
in? ( elt set -- ? ) ! is elt in the set?
null? ( set -- ? ) ! is the set empty?
cardinality ( set -- n ) ! number of elements
members ( set -- seq ) ! enumerate as a sequence
in? सेट-प्रोटोकॉल की सदस्यता जाँच है। यह member? (जो sequences से आता है) से अलग है, क्योंकि member? किसी सीक्वेंस पर एक-एक करके, यानी रैखिक रूप से, स्कैन करता है। हैश-सेट के लिए in? एक हैश लुकअप है, औसतन O(1), और हैश-सेट इस्तेमाल करने का पूरा फायदा यही है।
null? बताता है कि सेट में कोई एलिमेंट है या नहीं, यानी "क्या यह खाली है?" पूछने का सीधा तरीका, बजाय cardinality की शून्य से तुलना करने के।
: my-log ( -- set ) HS{ "NS-1024" "WB-203" } ;
"NS-1024" my-log in? . ! => t
"X-99" my-log in? . ! => f
my-log null? . ! => f
HS{ } clone null? . ! => t
my-log cardinality . ! => 2
union ( set1 set2 -- set )
intersect ( set1 set2 -- set )
diff ( set1 set2 -- set )
set-like ( set exemplar -- set' )
union का मतलब है "दोनों में से कोई भी एलिमेंट"; intersect का मतलब है "दोनों में मौजूद एलिमेंट"; और diff का मतलब है "जो set1 में है पर set2 में नहीं"। हर एक नया सेट लौटाता है और अपने इनपुट को नहीं बदलता।
set-like set को exemplar के टाइप में बदल देता है। union/intersect/diff के डिफ़ॉल्ट कार्यान्वयन इसी की मदद से नतीजे को रिसीवर के टाइप के मुताबिक बनाते हैं: <my-set> <hash-set> union एक my-set लौटाता है, हैश-सेट नहीं।
हैश-सेट, हैशटेबल के साथ ग्राफ ट्रैवर्सल में स्वाभाविक रूप से काम आते हैं: हैशटेबल हर नोड को उसके पड़ोसी नोड से जोड़ती है, और हैश-सेट दर्ज रखता है कि कौन-कौन से नोड पहले ही देखे जा चुके हैं, ताकि खोज में लूप न बने और काम दोहराया न जाए। इसके बाद ट्रैवर्सल के लिए एक क्यू और ये दो स्ट्रक्चर चाहिए, जिन्हें बाहर की ओर बढ़ते हुए मौके पर ही बदलते जाते हैं।
आप केप क्रोज़ियर प्रकाशस्तंभ के रखवाले हैं। लालटेन कक्ष से आप हर उस जहाज़ को दर्ज करते हैं जो वहाँ से गुज़रता है। हर जहाज़ की पहचान उसके अपने कॉलसाइन से होती है। इसके अलावा आप तट पर ऊपर-नीचे बने दूसरे प्रकाशस्तंभों के साथ सिग्नल रिले का समन्वय भी करते हैं।
empty-log को परिभाषित कीजिए, जो कॉलसाइन जमा करने के लिए तैयार एक नई, खाली हैश-सेट लौटाता है।
empty-log .
! => HS{ }
sight को परिभाषित कीजिए, जो एक लॉगबुक और एक कॉलसाइन लेता है और उस दिखाई देने की प्रविष्टि को उसी लॉगबुक में दर्ज कर देता है। कुछ नहीं लौटाता।
empty-log dup "NS-1024" sight .
! => HS{ "NS-1024" }
seen? को परिभाषित कीजिए, जो एक लॉगबुक और एक कॉलसाइन लेता है और अगर वह कॉलसाइन दर्ज हो चुका है तो t लौटाता है, वरना f।
HS{ "NS-1024" "WB-203" } "NS-1024" seen? . ! => t
HS{ "NS-1024" "WB-203" } "X-99" seen? . ! => f
forget-sighting को परिभाषित कीजिए, जो एक लॉगबुक और एक कॉलसाइन लेता है और उसी लॉगबुक में से वह कॉलसाइन हटा देता है। कुछ नहीं लौटाता। अगर वह कॉलसाइन वहाँ नहीं है, तो कुछ न कीजिए।
HS{ "NS-1024" "WB-203" } clone dup "WB-203" forget-sighting .
! => HS{ "NS-1024" }
unique-count को परिभाषित कीजिए, जो लॉग में मौजूद अलग-अलग कॉलसाइन की संख्या लौटाता है।
HS{ "NS-1024" "WB-203" "AC-77" } unique-count . ! => 3
empty-log unique-count . ! => 0
तटरक्षक बल एक relay-map रखता है। यह एक हैशटेबल है जिसमें प्रकाशस्तंभों के नाम कुंजी होते हैं, और हर नाम के सामने उन प्रकाशस्तंभों का एक ऐरे होता है जिन तक वह प्रकाशस्तंभ सीधे रिले भेज सकता है।
reachable को परिभाषित कीजिए, जो एक start प्रकाशस्तंभ और एक relay-map लेता है, और बार-बार रिले करने पर start से पहुँच में आने वाले हर प्रकाशस्तंभ का हैश-सेट लौटाता है, जिसमें start खुद भी शामिल है।
H{
{ "Crozier" { "Beacon" "Hadley" } }
{ "Beacon" { "Crozier" "Spiral" } }
{ "Hadley" { "Crozier" } }
{ "Spiral" { "Beacon" "Outpost" } }
{ "Outpost" { "Spiral" } }
{ "Far-Isle" { "Lonely" } }
{ "Lonely" { "Far-Isle" } }
}
"Crozier" swap reachable .
! => HS{ "Crozier" "Beacon" "Hadley" "Spiral" "Outpost" }
Far-Isle और Lonely की जोड़ी अपना एक अलग जुड़ा हुआ समूह बनाती है, इसलिए नतीजे में इनमें से कोई भी नहीं आता।
Exercism पर साइन अप कीजिए और Factor को 47 कॉन्सेप्ट163 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।