3
(define (associate lst)
    (if (or (null? lst) (= (length lst) 1))
        '()
        (cons (cons (car lst) (cadr lst)) (associate (cddr lst)))))

(define (disassociate lst)
    ;(display (caar lst))
    (if (null? lst)
        '()
        (cons (cons (caar lst) (cdar lst)) (disassociate (cdr lst)))))

(display (disassociate '((a . 1) (b . 2) (c . 3))))
(newline)
(display (associate '(a 1 b 2 c)))
(newline)

出力:

;; with list
((a 1) ((b 2) ((c 3) ())))
((a . 1) (b . 2))

;; with cons
((a . 1) (b . 2) (c . 3))
((a . 1) (b . 2))

の連想リストをフラット化しようとしていますが、を に変更しSchemeても括弧が上がり続けます。私は何か間違ったことをしていますか?listcons

4

2 に答える 2

3

でのリストの作成方法に誤りがありますdisassociate。これを試して:

(define (disassociate lst)
  (if (null? lst)
      '()
      (cons (caar lst)
            (cons (cdar lst) 
                  (disassociate (cdr lst))))))

または、次を使用しlist*ます。

(define (disassociate lst)
  (if (null? lst)
      '()
      (list* (caar lst)
             (cdar lst) 
             (disassociate (cdr lst)))))

上記は、連想リストが値を結合するために使用していることを前提としています。出力リストが最初の要素、次に 2 番目の要素を ing してから再帰を呼び出すことconsによってどのように作成されるかに注目してください。cons一方、連想リストがlist値を結合するために作成されたものである場合、これは関連付けを解除する方法です。

(define (disassociate lst)
  (if (null? lst)
      '()
      (cons (caar lst)
            (cons (cadar lst) ; here's the change
                  (disassociate (cdr lst))))))

または、次のようにします。

(define (disassociate lst)
  (if (null? lst)
      '()
      (list* (caar lst)
             (cadar lst) ; here's the change
             (disassociate (cdr lst)))))

より慣用的な解決策は、入力リストを処理するために高次の手順を使用することです。foldr質問で説明されている2つの連想リストバリアントを使用する方法は次のとおりです。

; associations created with cons
(define (disassociate lst)
  (foldr (lambda (pr ac) (list* (car pr) (cdr pr) ac))
         '()
         lst))

; associations created with list
(define (disassociate lst)
  (foldr (lambda (pr ac) (list* (car pr) (cadr pr) ac))
         '()
         lst))
于 2013-09-10T15:10:00.400 に答える