(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
中括起一个关联列表,但是括号
即使我将list
更改为cons
,也会继续调高。我做错了吗?
答案 0 :(得分: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)))))
以上假设关联列表正在使用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
表示问题中描述的两个关联列表变体的方法:
; 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))
答案 1 :(得分:3)
您的disassociate
行需要阅读:
(cons (caar lst) (cons (cdar lst) (disassociate (cdr lst)))))
准引用!有时这些使用准引用更清楚地实现,因为准引用可以让您看到结果列表结构。
(define (associate lst)
(if (or (null? lst) (null? (cdr lst)))
'()
`(,(cons (car lst) (cadr lst)) ,@(associate (cddr lst)))))
(define (disassociate lst)
(if (null? lst)
'()
`(,(caar lst) ,(cdar lst) ,@(disassociate (cdr lst)))))
> (associate (disassociate '((a . 1) (b . 2))))
((a . 1) (b . 2))
请注意,您还可以将associate
准引用写为:
`((,(car lst) . ,(cadr lst)) ,@(associate (cddr list)))))
但是对我来说开始变得越来越难以阅读,即使它使关联对显而易见。