问题描述
我是球拍编码的新手,但我想定义一个过程,以检查给定列表是否为另一个列表的子列表(或一部分)。
到目前为止,这是我的代码:
(define prefix?
(lambda (lst1 lst2)
(cond
((equal? lst1 lst2) #t)
((null? lst2) #f)
(else (prefix? lst1 (reverse (rest (reverse lst2))))))))
(define sublist?
(lambda (lst1 lst2)
(cond
((prefix? lst1 lst2) #t)
((null? lst2) #f)
(else (prefix? lst1 (rest lst2))))))
我已经尝试了大多数情况,并且按预期方式工作,但是当我尝试此测试用例时:
(sublist? '(a b d) '(a b c a b d e))
本应返回#t时返回#f 我尝试跟踪子列表?程序,但不会返回任何有用的信息。
解决方法
存在逻辑错误。 sublist?
的默认情况下应调用sublist?
,而应调用prefix?
,因此只有匹配项在索引0或1中时,您的prefix?
才为true。
您还创建了一个相当复杂的prefix?
。而不是一个一个地比较元素直到它们中的任何一个都为空,您要对最后一个元素进行O(n)删除,直到返回#f
之前有一个空列表,即使前两个元素不同。我将比较第一个元素,然后在两个参数中都重复使用rest
,直到其中一个列表为空。哪一个取决于结果,例如。在(prefix '(a b) '(w a d f s))
和a
之间进行首次检查之后,w
将停止计算。
尝试一下:
(define sub?
(lambda (l sub)
(define test (lambda (x) (equal? x sub)))
((lambda (s) (s s l test))
(lambda (s l k)
(or (k '())
(and (pair? l)
(s s (cdr l)
(lambda (r)
(or (test r)
(k (cons (car l) r)))))))))))
(sub? '(a b c a b d e) '(b d e) )
(sub? '(a b c a b d e) '(c a b) )
(sub? '(a b c a b d e) '(a b c) )
(sub? '(a b c a b x e) '(a b d) )