首先,如果有人能找到已经回答的问题,请告诉我。我能找到的只是删除重复的功能。
无论如何,我正在尝试编写一个方案函数(delete V L)
,它将值和列表作为参数,并从列表及其所有子列表中删除该值。例如,给出以下输入:
> (deep-delete 3 '(1 2 3 (4 3) 5 (6 (3 7)) 8))
它会产生:
(1 2 (4) 5 (6 (7)) 8)
到目前为止,这是我写的,但我知道if语句(检查元素是否是子列表,这意味着它也必须被操作)必须放错。此外,我无法将我的大脑包裹在我应该使用cons
的地方,而我不应该在哪里,因为我仍然对跟踪递归的返回值感到困惑。有人可以看看并解释我做错了什么吗?
(define (delete V L)
(if (list? (car L)) (cons (delete V (car L) (cdr L)))
(cond
((null? L) L)
((equal? V (car L)) (delete V (cdr L)))
(else (cons (car L) (delete V (cdr L))))))))
答案 0 :(得分:3)
我对您的代码有一些评论:
if
语句中,您使用(car L)
而不检查L
是否为空。(delete V (car L) (cdr L))
,
但是cons
有两个参数,而不是三个。而您忘记以delete
递归呼叫cdr
。
你自找的:
(cons (delete V (car L)) (delete V (cdr L)))
cond
?由于存在多种情况,使用cond
将使算法的递归结构更加明显,并且更容易捕获错误。见下文。
(define (del V L)
(cond ((null? L) L)
((list? (car L))
(cons (del V (car L)) (del V (cdr L))))
((equal? V (car L)) (del V (cdr L)))
(else (cons (car L) (del V (cdr L))))))
这将从V
递归删除L
。
(del 3 '(1 2 3 (4 3) 5 (6 (3 7)) 8))
==> (1 2 (4) 5 (6 (7)) 8)
答案 1 :(得分:1)
这很容易实现折叠;这是使用foldr
:
(define (deep-delete elt lst (test equal?))
(foldr (lambda (e r)
(if (list? e)
(cons (deep-delete elt e test) r)
(if (test elt e) r (cons e r))))
null
lst))
测试
> (deep-delete 3 '(1 2 3 (4 3) 5 (6 (3 7)) 8))
'(1 2 (4) 5 (6 (7)) 8)
答案 2 :(得分:1)
这将从树中删除子树(包括原子树):
(define (remove-element needle haystack)
(let rec ((haystack haystack))
(cond
((equal? needle haystack) '())
((not (pair? haystack)) haystack)
((equal? needle (car haystack)) (rec (cdr haystack)))
((equal? needle (cdr haystack)) (cons (rec (car haystack)) '()))
(else (cons (rec (car haystack))
(rec (cdr haystack)))))))
(remove-element 'atom 'atom) ; => ()
(remove-element '(1 2 3) '((1 2 3) 1 2 3)) ; => ()
(remove-element '(1 2 3) '((1 2 3) 4 5 6)) ; => (4 5 6)
(remove-element '(1 2 3) '(3 2 1 2 3)) ; ==> (3 2)
(remove-element '3 '((1 2 3) 1 2 3)) ; ==> ((1 2) 1 2)
(remove-element '(1 2 3) '(1 2 3 4)) ; ==> (1 2 3 4)