Подсчет количества совпадений для каждого подсписка отдельно - PullRequest
0 голосов
/ 05 мая 2018

Вот мой большой список с подсписками:

   (define family
      (list
       (list 'Daddy 't-shirt 'raincoat 'sunglasses 'pants 'coat 'sneakers)
       (list 'Mamma 'high-heels 'dress 'pants 'sunglasses 'scarf)
       (list 'son 'pants 'sunglasses 'sneakers 't-shirt 'jacket)
       (list 'daughter 'bikini 'Leggings 'sneakers 'blouse 'top)))

И я хочу сравнить family с этим простым списком:

   (list 'sneakers 'dress 'pants 'sunglasses 'scarf)

каждое совпадение должно давать 1 балл, и я хочу, чтобы этот балл рассчитывался отдельно для каждого подсписка.

Вот код:

; проверка наличия элемента в списке

(define occurs?
  (lambda (element lst)                  
    (cond
      [(and (null? element) (null? lst))] 
      [(null? lst) #f]
      [(pair?  lst)
       (if
        (occurs? element (car lst)) #t
        (occurs? element (cdr lst)))]
      [else (eqv? element lst)])))
;--------------------------------------    

; создается список только имен.

(define (name-list lst)
  (list (map car lst)))

; У каждого подсписка есть имя (машина подсписка). Список имен превращается в список точек для каждого подсписка. Весь мой код, за исключением кода ниже, работает так, как я хочу. Проблема заключается в point-list коде.

(define (point lst db)
  (let ((no-point (name-list db)))
    (cond ((or (null? lst) (null? db)) '())
          (set! (first no-point) (comp lst (rest db)))
          (else (point lst (cdr db))))))

Папа-подсписок имеет 3 общих элемента. Mamma-sublist имеет 4 общих элемента, son-sublist 3 элемента и daugther-sublist 1 элемент.

Я хочу, чтобы исходные данные были такими:

> (comparison (list 'sneakers 'dress 'pants 'sunglasses 'scarf) family)
'(3 4 3 1)

Мой код не работает так, как я хочу. Я получаю это Eror:

set!: bad syntax in: set!

Может ли кто-нибудь гид объяснить мне, что делать?

1 Ответ

0 голосов
/ 05 мая 2018

У вас неверный синтаксис с set!:

          (set! (first no-point-lst) (comparison lst (rest db)))

Это недопустимое использование set!, попытка "изменить структуру" списка no-point-lst, изменяя то, что фактически удерживается в его первой позиции.

set! не может этого сделать. Его можно использовать для изменения привязки, т. Е. Значения переменной: (let ((a 1)) (set! a 2)).

В Common Lisp они могут писать (setf (first list) newval), но не в Scheme / Racket.

Если это важно для вашего алгоритма, вы можете использовать set-car! в R5RS Scheme или set-mcar! в Racket. Или вы можете сделать это с векторами .

Но вы также можете реструктурировать свой код как

        (set! no-points-list 
              (cons 
                 (comparison lst (rest db))
                 (cdr no-points-list)))
...