Emacs lisp में दो सेट के बीच अंतर की गणना कैसे करें, सेट सूची होना चाहिए




elisp set (4)

Emacs Lisp में दो सेट के बीच अंतर की गणना कैसे करें? सेट सूची होना चाहिए। प्रोग्राम बहुत सरल और छोटा होना चाहिए, अन्यथा मैं इसे समझ नहीं पाता। मैं एक नौसिखिया हूँ

धन्यवाद


अस्वीकरण: यह ईलिस में ऐसा करने का एक कारगर तरीका नहीं है। एक हैश फ़ंक्शन के साथ एक हैश-तालिका के माध्यम से एक प्रभावी तरीका है, लेकिन जब आप सूचियों के बारे में पूछा, तो यहां यह है:

(defun custom-set-difference (a b)
  (remove-if
     #'(lambda (x) (and (member x a) (member x b)))
     (append a b)))

(custom-set-difference '(1 2 3 4 5) '(2 4 6))

(1 3 5 6)

(defun another-set-difference (a b)
  (if (null a) b
    (let (removed)
      (labels ((find-and-remove
                (c)
                (cond
                 ((null c) nil)
                 ((equal (car c) (car a))
                  (setq removed t) (cdr c))
                 (t (cons (car c) (find-and-remove (cdr c)))))))
        (setf b (find-and-remove b))
        (if removed
            (another-set-difference (cdr a) b)
          (cons (car a) (another-set-difference (cdr a) b)))))))

(another-set-difference '(1 2 3 4 5) '(2 4 6))

(1 3 5 6)

दूसरा थोड़ा और अधिक कुशल है, क्योंकि यह तत्वों को निकाल देगा क्योंकि यह फलस्वरूप जांच करता है, लेकिन पहले कम और अधिक सीधे-आगे है।

यह भी ध्यान रखें कि सूचियों को सेट का अच्छा प्रतिनिधित्व नहीं है क्योंकि वे पुनरावृत्ति की अनुमति देते हैं। हैश नक्शे उस प्रयोजन के लिए बेहतर हैं


जब मैं एलिसिप कोड लिखता हूं जिसमें बहुत सारे डेटा डेटा परिवर्तन होता है, तो मैं dash लाइब्रेरी का उपयोग करता हूं, क्योंकि इसमें सूचियों के साथ काम करने के लिए फ़ंक्शन का भार है सेट अंतर के साथ किया जा सकता है अंतर:

(-difference '(1 2 3 4) '(3 4 5 6)) ;; => '(1 2)

यहां एक सरल और संक्षिप्त परिभाषा है, जिसे समझना आसान होना चाहिए। यह अनिवार्य रूप से इमैक के लिए आम लिस्प पुस्तकालय में set-difference फ़ंक्शन के समान है, लेकिन एक परीक्षण तर्क के किसी भी उपचार के बिना।

(defun set-diff (list1 list2 &optional key)
  "Combine LIST1 and LIST2 using a set-difference operation.
Optional arg KEY is a function used to extract the part of each list
item to compare.

The result list contains all items that appear in LIST1 but not LIST2.
This is non-destructive; it makes a copy of the data if necessary, to
avoid corrupting the original LIST1 and LIST2."
  (if (or (null list1)  (null list2))
      list1
    (let ((keyed-list2  (and key  (mapcar key list2)))
          (result       ()))
      (while list1
        (unless (if key
                    (member (funcall key (car list1)) keyed-list2)
                  (member (car list1) list2))
          (setq result  (cons (car list1) result)))
        (setq list1  (cdr list1)))
      result)))

सामान्य लिस्प एक्सटेंशन में एक set-difference फंक्शन फ़ंक्शन होता है:

elisp> (require 'cl)
cl
elisp> (set-difference '(1 2 3) '(2 3 4))
(1)