如何在方案中定义集合

时间:2014-04-07 00:27:57

标签: scheme

我在使用我的会员时遇到了麻烦?功能。我需要递上我的套装吗?功能直到我列表中的最后一个元素' lst'到达了。我相信我的导航正确,但也许我的输入语法是错误的。我知道有三种情况:

1)如果列表为空,会发生什么?这意味着它没有任何重复 2)如果列表的当前元素存在于列表的其余部分,会发生什么?那意味着列表中有一个副本(提示:成员过程可能有用) 3)如果以上都不是真的,继续下一个元素。

这是我的代码。

(define (member? e lst)
(if (null? lst) #f 
(if (equal? e (car lst)) #t
(member? e (cdr lst)))))

(define (set? lst)      
(if (null? lst) #t                 ;Case1
(if (member? (car lst) lst) #f     ;Case2
(set? (cdr lst)))))                ;Case3

;Example tests for the set? function
(set? '(x y z))
(set? '(a 1 b 2 c 3))
(set? '())
(set? '(6 2 2))
(set? '(x y z x))

1 个答案:

答案 0 :(得分:3)

您的代码存在一个小错误,看看它是如何修复的:

(define (set? lst)      
  (if (null? lst)
      #t
      (if (member? (car lst) (cdr lst)) ; in here
          #f
          (set? (cdr lst)))))

特别注意这条线的作用:

(member? (car lst) lst)

这不起作用:测试是检查lst中的第一个元素是否是lst的成员 - 并且总是如此。解决方案很简单,只需检查当前元素是否在列表的 rest 中,如果它在那里,那么我们知道我们发现了重复:

(member? (car lst) (cdr lst))

顺便说一下,使用cond上面的代码看起来会更好,当你嵌套if时这很好:

(define (set? lst)      
  (cond ((null? lst) #t)
        ((member? (car lst) (cdr lst)) #f)
        (else (set? (cdr lst)))))