实施子列表?在Racket中使用累积

时间:2016-09-29 02:45:13

标签: scheme racket member sublist accumulate

我需要实现子列表?作为使用累积的单线函数。 如果set1在set2中,则假设返回true。

这样的事情:

(define subset?
  (lambda (set1 set2)
    (accumulate member? (car set1) (lambda (x) x) set2)))

老实说,我认为我对如何与成员合作,或者成员甚至是运营商的正确选择感到困惑。

我的累积功能是:

(define accumulate
  (lambda (op base func ls)
    (if (null? ls)
      base
      (op (func (car ls))
        (accumulate op base func (cdr ls))))))

和成员?:

(define member?
  (lambda (item ls)
    (cond ((null? ls) #f)
      ((equal? item (car ls)) #t)
        (else (member? item (cdr ls))))))

1 个答案:

答案 0 :(得分:1)

要首先给出subset?的正确定义,我们必须了解函数accumulate的工作原理及其参数的含义。

如果我们“展开”递归定义,我们可以看到accumulate将二元运算符op应用于将func应用于列表{{1}的元素的所有结果}。由于列表可以为空,因此在这些情况下,函数被定义为返回值ls

因此,例如,假设函数的递归执行,下面的表达式

base

产生14,因为它相当于:

(accumulate + 0 sqr '(1 2 3))

即1 + 4 + 9 + 0。

要解决您的问题,您必须定义对(+ (sqr 1) (+ (sqr 2) (+ (sqr 3) 0))) 的调用,该调用将相同的运算符应用于元素列表,然后组合结果。在您的情况下,如果元素是列表的成员(accumulate),则要应用的操作是测试,并且您可以将其应用于member?的所有元素。并且,从子集的定义,您应该知道,当且仅当s1的所有元素都包含在s2中时,集合s1是另一个集合s2的子集。因此,必须应用于结合测试的所有结果的运算符只是set1布尔运算符,因此如果 all s1的元素是s2的成员,则它将为true否则是假的。最后要决定的是基值:这应该是真的,因为空集总是包含在另一个集合中。

所以这是and

的可能定义
subset?