从列表和子列表中删除成员的Scheme函数

时间:2014-09-24 15:48:00

标签: list recursion scheme member

首先,如果有人能找到已经回答的问题,请告诉我。我能找到的只是删除重复的功能。

无论如何,我正在尝试编写一个方案函数(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))))))))

3 个答案:

答案 0 :(得分:3)

我对您的代码有一些评论:

  • 首先,在if语句中,您使用(car L)而不检查L是否为空。
  • 此外,在代码的第2行中,您执行:(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

的Racket中的示例
(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)