我刚刚开始学习可变数据,并在使用set!
命令时以递归方式处理列表时遇到一些问题。虽然我的大多数方法在这个函数中都能正常工作,但删除和基数函数却没有,而且我不确定如何在这种函数中解决这个问题。
(define (basic-set)
(let ((set '()))
(define (empty?)
(null? set))
(define (insert s)
(set! set (cons s set)))
(define (delete s)
(cond ((equal? (car set) s)(set! set (cons (cdr set)'())))
(else ((delete s)(cdr set)))))
(define (element? s)
(cond ((equal? (car set) s)#t)
(else ((element? s)(cdr set)))))
(define (cardinality)
(cond ((null? set)0)
(else
(+ 1 ((cardinality)(cdr set))))))
(lambda (method)
(cond ((eq? method 'empty) empty?)
((eq? method 'insert) insert)
((eq? method 'delete) delete)
((eq? method 'element) element?)
((eq? method 'cardinality) cardinality)))))
答案 0 :(得分:2)
您必须小心实施delete
,element?
和cardinality
的方式 - 这些程序必须迭代存储为可变数据的集合,为此您必须要将集合作为参数传递,我会使用名为let
。
此外,实现delete
是棘手的,正确的方法是消除元素,然后在最后更新状态。这就是我的意思:
(define (basic-set)
(let ((set '()))
(define (empty?)
(null? set))
(define (insert s)
(set! set (cons s set)))
(define (delete s)
(define (helper set)
(cond ((null? set) '())
((equal? (car set) s) (cdr set))
(else (cons (car set) (helper (cdr set))))))
(set! set (helper set)))
(define (element? s)
(let loop ((set set))
(cond ((null? set) #f)
((equal? (car set) s) #t)
(else (loop (cdr set))))))
(define (cardinality)
(let loop ((set set))
(cond ((null? set) 0)
(else (+ 1 (loop (cdr set)))))))
(lambda (method)
(cond ((eq? method 'empty) empty?)
((eq? method 'insert) insert)
((eq? method 'delete) delete)
((eq? method 'element) element?)
((eq? method 'cardinality) cardinality)))))
例如:
(define s (basic-set))
((s 'insert) 'x)
((s 'insert) 'y)
((s 'element) 'x)
=> #t
((s 'cardinality))
=> 2
((s 'delete) 'x)
((s 'cardinality))
=> 1
((s 'empty))
=> #f
答案 1 :(得分:0)
这里的另一种方法是将匿名函数与外部接口arity匹配到内部方法arity,就像这样。当然比奥斯卡的解决方案更丑陋,但有时候在你担心漂亮之前让它发挥作用是最好的。
(define (basic-set)
(let ((set '()))
(define (empty?)
(null? set))
(define (insert s)
(set! set (cons s set)))
(define (delete s L)
(set! set
(let loop ((L L))
(cond ((null? L) '())
((equal? (car L) s) (cdr L))
(else (cons (car L) (loop (cdr L)))))))
(define (element? s L)
(cond ((equal? (car L) s) #t)
(else (element? s (cdr L)))))
(define (cardinality L)
(cond ((null? L) 0)
(else
(+ 1 ((cardinality)(cdr L))))))
(lambda (method)
(cond ((eq? method 'empty) empty?)
((eq? method 'insert) insert)
((eq? method 'delete) (lambda (s) (delete s set)))
((eq? method 'element) (lambda (s) (element? s set)))
((eq? method 'cardinality) (lambda () (cardinality set)))))))