Добавление элемента в список в схеме - PullRequest
1 голос
/ 30 марта 2010

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

thx заранее ..

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

Ответы [ 4 ]

1 голос
/ 30 марта 2010

Вот рекурсивная версия, которая выполняет пересечение вместо объединения.

(define (intersect list1 list2)
  (cond ((null? list1)   list1)
        ((member (car list1) list2)   (cons (car list1) (intersect (cdr list1) list2)))
        (t   (intersect (cdr list1) list2))))
0 голосов
/ 30 марта 2010

Вам лучше использовать операции установки из srfi-1.

0 голосов
/ 30 марта 2010

Мне кажется, я вижу твою проблему. Есть два способа добавить элемент в список.

Первый способ - добавить его:

(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)))))
0 голосов
/ 30 марта 2010

Вот несколько упрощений:

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