Вопрос

Я использую схему R5RS и просто хочу реализовать функцию, которая возвращает пересечение двух заданных списков, но я не могу этого сделать, потому что не могу добавить элемент в список.Вот мой код.Как я могу это исправить?Я действительно новичок в Scheme — это моя первая работа с использованием Scheme.

спасибо заранее..

(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)

Вам лучше использовать набор операций из СРФИ-1.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top