2008-09-19 21 views
6

मेरे पास दो अपरिवर्तित सूचियां हैं और मुझे एक और सूची तैयार करने की आवश्यकता है जो सॉर्ट किया गया है और जहां सभी तत्व अद्वितीय हैं।मुझे दो सूचियों में शामिल होने, उन्हें क्रमबद्ध करने और डुप्लीकेट हटाने की आवश्यकता है। क्या ऐसा करने के लिए इससे अच्छा तरीका है?

तत्व दोनों सूचियों में कई बार हो सकते हैं और वे मूल रूप से अपरिवर्तित हैं।

मेरे समारोह इस तरह दिखता है:

(defun merge-lists (list-a list-b sort-fn) 
    "Merges two lists of (x, y) coordinates sorting them and removing dupes" 
    (let ((prev nil)) 
     (remove-if 
      (lambda (point) 
       (let ((ret-val (equal point prev))) 
        (setf prev point) 
        ret-val)) 
      (sort 
       (merge 'list list-a list-b sort-fn) ;' 
       sort-fn)))) 

वहाँ एक ही प्राप्त करने के लिए एक बेहतर तरीका है?

नमूना कॉल:

[CL]> (merge-lists '(9 8 4 8 9 7 2) '(1 7 3 9 2 6) #'>) 
    ==> (9 8 7 6 4 3 2 1) 
+0

आप "बेहतर" के साथ क्या मतलब है यह स्पष्ट करना चाहते हैं। – mweerden

+0

क्या आपने अनचाहे स्निपेट को आजमाया और क्या यह काम किया? मुझे अपना जवाब संपादित करना अच्छा लगेगा ताकि हमारे बाद की पीढ़ी को अपने लिस्प 3000 को दुर्घटनाग्रस्त स्निपेट के डर में नहीं रहना पड़े ... –

+0

मैंने वास्तव में इसका परीक्षण किया और यह वास्तव में काम करता था। उत्तर के लिए बहुत धन्यवाद। – dsm

उत्तर

11

हमारे पड़ोस के अनुकूल लिस्प गुरु ने remove-duplicates function को इंगित किया।

उन्होंने यह भी निम्नलिखित स्निपेट उपलब्ध:

(defun merge-lists (list-a list-b sort-fn test-fn) 
    (sort (remove-duplicates (append list-a list-b) :test test-fn) sort-fn)) 
+0

मुझे पता था कि ऐसा करने का एक शानदार तरीका था :) – dsm

+0

यह _not_ सुरुचिपूर्ण है - यह सबसे लंबी सूची की लंबाई में रैखिकथात्मक की बजाय सूचियों की लंबाई के बराबर _quadratic_ है। – sds

1

मुझे लगता है कि मैं पहली बार दो सूचियों अलग से सॉर्ट और फिर उन्हें एक समारोह है कि यह भी डुप्लिकेट से अधिक छोड़ देता है के साथ विलय होगा। यह थोड़ा तेज़ होना चाहिए क्योंकि इसे दोनों सूचियों के एक कम ट्रैवर्सल की आवश्यकता होती है।

पीएस .: मुझे संदेह है कि इसे बहुत तेज किया जा सकता है क्योंकि आपको मूल रूप से कम से कम एक प्रकार की आवश्यकता होती है और एक विलय होता है। शायद आप दोनों एक समारोह में गठबंधन कर सकते हैं, लेकिन अगर मैं (बड़ा) अंतर नहीं करता तो मुझे आश्चर्य नहीं होगा।

-2

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

+0

सेट आमतौर पर क्रमबद्ध नहीं होते हैं। –

+0

आरकिट्टन के पास एक बिंदु है। यदि सेट का उपयोग करना आसान है, तो किसी को पहले स्थान पर डुप्लीकेट से निपटना नहीं पड़ता है। दूसरी तरफ, सेट्स का उपयोग करने के लिए डीएसएम द्वारा पूर्णांक में उपयोग किए जाने वाले जानवरों से मानचित्रण करने की आवश्यकता होती है। यह अनौपचारिक लगता है। मैं यहां एक समान प्रश्न के साथ आया था, और पूर्णांक के लिए मैपिंग आसान नहीं होता। –

1

तो इससे पहले कि आप उन्हें मर्ज सूचियों हल कर रहे हैं, वे विलय कर दिया जा सकता है, नकली-हटा दिया और एक ही समय में हल कर। अगर वे सॉर्ट और डुप्लिकेट-फ्री हैं, तो मर्ज/सॉर्ट/डुप्लिकेट-फ़ंक्शन फ़ंक्शन वास्तव में तुच्छ हो जाता है।

वास्तव में, यह आपके सम्मिलित फ़ंक्शन को बदलना बेहतर हो सकता है ताकि यह एक क्रमबद्ध प्रविष्टि निष्पादित करता है जो डुप्लीकेट के लिए जांच करता है। फिर आप हमेशा सूचियों को क्रमबद्ध करते हैं जो डुप्लिकेट से मुक्त होते हैं, और उन्हें विलय करना एक मामूली मामला है।

फिर, आप बाद में डुप्लिकेट को सॉर्ट करने/हटाने की लागत पर एक तेज सम्मिलित कार्य करना पसंद कर सकते हैं।

0

अगर हटाए गए डुप्लिकेट से पहले सॉर्ट लागू किया गया था तो हटाए गए डुप्लिकेट फ़ंक्शन बेहतर काम नहीं करेंगे?

+0

शायद नहीं। हाइपरस्पेक के मुताबिक सूची को आदेश देने की आवश्यकता नहीं है। –

0

अंटी के रूप में बताया, तो आप शायद, हटाने-डुप्लिकेट और SORT लाभ उठाने के लिए हालांकि मैं शायद परीक्षण समारोह के लिए एक कीवर्ड (या वैकल्पिक तर्क) का उपयोग करेंगे चाहते हैं: (defun मर्ज-सूची (सूची -1 सूची- 2 तरह-fn & कुंजी (परीक्षण # 'eql)) ...) या (defun मर्ज-सूची (सूची -1 सूची -2 तरह-fn & वैकल्पिक (परीक्षण #' eql) ...)

इस तरह, आपको टेस्ट फ़ंक्शन निर्दिष्ट नहीं करना होगा ("इन्हें डुप्लिकेट माना जाता है" के परीक्षण के लिए रिमूव-डुप्लिकेट्स द्वारा उपयोग किया जाता है), जब तक कि ईक्यूएल पर्याप्त न हो।