سؤال

أنا أستخدم مخطط R5RS وأريد فقط تنفيذ وظيفة تُرجع تقاطع قائمتين معينتين ، لكن لا يمكنني فعل ذلك لأنني لا أستطيع إضافة عنصر إلى قائمة. ها هو الكود الخاص بي. كيف يمكنني إصلاح ذلك؟ أنا حقًا مبتدئ في المخطط - هذا هو عملي الأول باستخدام المخطط.

تشك مقدما ..

(define list3 '())
(define (E7 list1 list2)

        (cond
          ((null? list1)
          list3)
          ((member (car list1) list2) (append list3 (list (car list1))))

        )
  (cond
          ((null? list1)
          list3)
          ((not(null? list1)) (E7 (cdr list1) list2)

        )

     )


)
(E7 '(4 5) '(3 4))
هل كانت مفيدة؟

المحلول

فيما يلي نسخة متكررة تقوم بالتقاطع بدلاً من الاتحاد.

(define (intersect list1 list2)
  (cond ((null? list1)   list1)
        ((member (car list1) list2)   (cons (car list1) (intersect (cdr list1) list2)))
        (t   (intersect (cdr list1) list2))))

نصائح أخرى

أعتقد أنني أرى مشكلتك. هناك طريقتان لإضافة عنصر إلى قائمة.

الطريقة الأولى هي في الواقع إضافتها:

(define (intersect list1 list2)
  (define newlist list2)
  (do ((iter1 list1 (cdr iter1)))
    (not (null? iter1))
    (if (not (member (car iter1) newlist))
        (set! newlist (cons (car iter1) newlist)))))

(ربما يتعين عليك البحث عن تعريف do إذا كنت تريد حقًا استخدام هذا.)

قد تلاحظ أن هذا قبيح للغاية. ذلك لأن لا أحد يفعل ذلك بالفعل بهذه الطريقة. بدلاً من ذلك ، عليك أن تدرك أن استدعاء الوظيفة يخلق متغيرًا جديدًا أيضًا. جرب هذا:

(define (intersect list1 list2)
  (cond ((null? list1) list2)
        ((member (car list1) list2) (intersect (cdr list1) list2))
        (else (intersect (cdr list1) (cons (car list1) list2)))))

إذا كنت معتادًا على الخوارزميات ، فستلاحظ أن الكود الذي كتبته بطيئًا جدًا ، لكنه يوضح النقطة: في كل حالة ، تقوم ببعض العمل ثم اتصل بوظيفتك مرة أخرى. إذا كنت تواجه مشكلة في معرفة سبب عمل هذه الوظيفة ، فقم بتشغيل هذه الوظيفة بدلاً من ذلك على مثالك:

(define (intersect list1 list2)
  (display list1) (display " ") (display list2) (newline)
  (cond ((null? list1) list2)
        ((member (car list1) list2) (intersect (cdr list1) list2))
        (else (intersect (cdr list1) (cons (car list1) list2)))))

هنا بعض التبسيط Elisp:

(defun is (l1 l2)
  (let ((rtn))
    (mapc
      (lambda (e) 
        (if (member e l1)
          (push e rtn)))
      l2)
    rtn))

هذا يتصرف مثل التقاطع المدمج لهذه الاختبارات البسيطة:

(is '(1 2 5) '(1 4 10 5))  => (5 1)
(intersection '(1 2 5) '(1 4 10 5)) => (5 1)

(is '(1 4 10 5) '(1 2 5)) => (5 1)
(intersection '(1 4 10 5) '(1 2 5)) => (5 1)

أنت أفضل حالًا في الاستخدام تعيين العمليات من SRFI-1.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top