我刚刚开始学习可变数据,并且在使用 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)))))
最佳答案
您必须小心实现 delete
、element?
和 cardinality
的方式 - 这些过程必须迭代所包含的集合存储为可变数据,为此您必须将集合作为参数传递,我将使用命名的 let
来实现。
此外,实现删除是很棘手的,正确的方法是删除元素,然后在最后更新状态。这就是我的意思:
(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
关于scheme - 在方案中操作可变数据中的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33990782/