2008-10-03 11 views
9

मुझे this जैसे कुछ चाहिए, तत्वों का एक संग्रह जिसमें किसी भी तत्व का कोई डुप्लिकेट नहीं है। क्या आम लिस्प, विशेष रूप से एसबीसीएल, इस तरह की कोई चीज़ है?क्या आम लिस्प में जावा के सेट इंटरफ़ेस/कार्यान्वयन कक्षाओं की तरह कुछ है?

उत्तर

1

ऐसा नहीं है कि मैं के बारे में पता कर रहा हूँ, लेकिन आप काफी कुछ इसी तरह के लिए hash tables उपयोग कर सकते हैं।

0

लिस्प हैशटेबल CLOS आधारित हैं। चश्मा here

+0

उम्म ... सीएलओएस मानक हैश टेबल _are_ CLOS क्लास हैश-टेबल का उदाहरण, जिसे आप बिना किसी चिंता के तरीकों को परिभाषित कर सकते हैं। इसके अलावा, जिस लेख से आप लिंक करते हैं, वह एक प्रकार की ऑब्जेक्ट सिस्टम के बारे में बात करता है जो कि CLOS की तरह नहीं है। सीएलओएस में, विधियां जेनेरिक फ़ंक्शंस से संबंधित हैं, ऑब्जेक्ट्स नहीं। –

+0

मेरा बुरा .... मैं प्रतिक्रिया संपादित कर रहा हूं – dsm

+1

सामान्य लिस्प हैशटेबल CLOS में लिपटे हैं। मुझे नहीं पता कि वे किस तरह से "CLOS आधारित" हैं। सीएलटीएल 1 में हैशटेबल थे लेकिन उदाहरण के लिए कोई सीएलओएस नहीं था। – Ken

6

एक त्वरित समाधान के लिए, बस हैश टेबल का उपयोग करें, जैसा कि पहले उल्लेख किया गया है।

हालांकि, यदि आप अधिक सिद्धांतबद्ध दृष्टिकोण पसंद करते हैं, तो आप FSet पर एक नज़र डाल सकते हैं, जो "एक कार्यात्मक सेट-सैद्धांतिक संग्रह लाइब्रेरी" है। दूसरों के बीच, इसमें सेट और बैग के लिए कक्षाएं और संचालन शामिल हैं।

(संपादित करें :) स्पष्ट तरीका शायद सामान्य कार्यों के रूप में अपने सेट उन्मुख आपरेशनों को परिभाषित करने के लिए होगा। सामान्य कार्यों का एक सेट मूल रूप से एक जावा इंटरफेस के बराबर है, आखिरकार। आप मानक हैश-टेबल वर्ग पर पहले प्रोटोटाइप के रूप में विधियों को आसानी से कार्यान्वित कर सकते हैं और अन्य कार्यान्वयनों को भी अनुमति दे सकते हैं।

5

आप सूचियों का उपयोग कर सकता है, हालांकि वे बड़े सेट का प्रतिनिधित्व करने के लिए अक्षम साबित हो सकता है। यह सूची में नया तत्व जोड़ने के लिए ADJOIN या PUSHNEW का उपयोग करके किया जाता है, और विपरीत करने के लिए DELETE or REMOVE। के लिए बाहर देखने के लिए

(let ((set (list))) 
    (pushnew 11 set) 
    (pushnew 42 set) 
    (pushnew 11 set) 
    (print set) ; set={42,11} 
    (setq set (delete 42 set)) 
    (print set)) ; set={11} 

एक बात सब है कि इन ऑपरेटरों डिफ़ॉल्ट रूप से EQL का उपयोग सेट में संभावित डुप्लीकेट के लिए परीक्षण करने के लिए (जावा के रूप में ज्यादा बराबरी विधि का उपयोग करता)। संख्याओं या पात्रों को रखने वाले सेट के लिए यह ठीक है, लेकिन अन्य ऑब्जेक्ट्स के सेट के लिए, 'गहरा' समानता परीक्षण जैसे EQUAL को निम्न कीवर्ड कीवर्ड पैरामीटर के रूप में निर्दिष्ट किया जाना चाहिए, उदा। तार का एक सेट के लिए: -

(let ((set (list))) 
    (pushnew "foo" set :test #'equal) 
    (pushnew "bar" set :test #'equal) 
    (pushnew "foo" set :test #'equal) ; EQUAL decides that "foo"="foo" 
    (print set)) ; set={"bar","foo"} 

जावा के सेट के संचालन में से कुछ के लिस्प के समकक्षों हैं:

+0

यह बाद में अनुकूलित करने के लिए एक अनुशंसित दृष्टिकोण है, बाद में अनुकूलन करना चाहिए सुझाव देना चाहिए कि इसकी आवश्यकता है। – wentbackward

5

हां, यह सेट है। प्रैक्टिकल कॉमन लिस्प से this section on "Sets" देखें।

मूल रूप से, आप, pushnew और adjoin के साथ एक सेट बनाने के member, member-if और member-if-not साथ क्वेरी, और intersection, union, set-difference, set-exclusive-or और subsetp जैसे कार्यों के साथ अन्य सेट के साथ यह गठजोड़ कर सकते हैं।

+6

सिवाय इसके कि यह कुछ दर्जन तत्वों से ऊपर नहीं है ... –

2

आसानी से हैश तालिका का उपयोग कर हल करने योग्य।

(let ((h (make-hash-table :test 'equalp))) ; if you're storing symbols 
    (loop for i from 0 upto 20 
     do (setf (gethash i h) (format nil "Value ~A" i))) 
    (loop for i from 10 upto 30 
     do (setf (gethash i h) (format nil "~A eulaV" i))) 
    (loop for k being the hash-keys of h using (hash-value v) 
     do (format t "~A => ~A~%" k v))) 

आउटपुट

0 => Value 0 
1 => Value 1 
... 
9 => Value 9 
10 => 10 eulaV 
11 => 11 eulaV 
... 
29 => 29 eulaV 
30 => 30 eulaV 
0

व्यक्तिगत रूप से, मैं सिर्फ एक समारोह जो एक सूची लेता है को लागू करने और एक अद्वितीय सेट लौट आते हैं। मैं एक साथ जो कुछ मेरे लिए काम करता मसौदा तैयार किया गया है:

(defun make-set (list-in &optional (list-out '())) 
    (if (endp list-in) 
     (nreverse list-out) 
     (make-set 
     (cdr list-in) 
     (adjoin (car list-in) list-out :test 'equal)))) 

असल में, adjoin समारोह एक सूची के लिए एक आइटम पहले जोड़ता गैर विध्वंस यदि और केवल यदि आइटम नहीं है सूची में पहले से ही मौजूद एक वैकल्पिक परीक्षण को स्वीकार समारोह (सामान्य लिस्प "बराबर" कार्यों में से एक)। आप इतनी विनाशकारी तरीके से करने के लिए pushnew का भी उपयोग कर सकते हैं, लेकिन मुझे पूंछ-पुनरावर्ती कार्यान्वयन कहीं अधिक सुरुचिपूर्ण लगता है। इसलिए, लिस्प कई बुनियादी कार्यों को निर्यात करता है जो आपको एक सूची के रूप में एक सूची का उपयोग करने की अनुमति देता है; कोई अंतर्निहित डेटाटाइप की आवश्यकता नहीं है क्योंकि आप केवल सूची में चीजों को पूर्ववत करने के लिए विभिन्न कार्यों का उपयोग कर सकते हैं।

इस सब के लिए मेरा डेटा स्रोत (फ़ंक्शन नहीं, लेकिन जानकारी) Common Lisp HyperSpec और Common Lisp the Language (2nd Edition) का संयोजन रहा है।