Reputation: 27
I need make a boolean function for evaluating two list,for example:
(define list1 '((1 2) (4 5) (8 6) (2 8)))
(define list2 '((1 2) (8 6)))
list2
is a sublist of list1
, and must returned #t
, but I don't know how do it, I try with this function for comparing two list
(define (sublist? lst1 lst2)
(if (null? lst2)
#f
(if(list? (car lst2))
(sublist? lst1 (car lst2))
(if (and(equal? car(lst1) (car lst2)) (equal? cdr(lst1) (car lst2)))
#t (sublist? lst1 (cdr lst2))))))
help :(
Upvotes: 2
Views: 1306
Reputation: 31147
This sublist?
behaves as a "subset?".
; sublist? : list list -> "boolean"
; return non-false if all elements of xs are in ys
(define (sublist? xs ys)
(or (null? xs) ; the empty list is a sublist of ys
(and ; for a non-empty list
(member (car xs) ys) ; the first element must be in ys
(sublist? (cdr xs) ys)))) ; and the rest of the elements as well.
This sublist?
behaves as a "substring?"
; prefix? : list list -> boolean
; is xs a prefix of ys?
(define (prefix? xs ys)
(or (null? xs)
(and (equal? (car xs) (car ys))
(prefix? (cdr xs) (cdr ys)))))
; sublist? : list list -> boolean
; is xs a consecutive sublist of ys?
(define (sublist? xs ys)
(or (null? xs)
(prefix? xs ys)
(and (not (null? ys))
(prefix? xs (cdr ys)))))
Upvotes: 1
Reputation: 53535
A suggested solution:
(define list1 '((1 2) (4 5) (8 6) (2 8)))
(define list2 '((4 5) (8 6)))
(define (sublist? lst1 lst2)
(if (null? lst2)
#t
(if (and (null? lst1)
(not (null? lst2)))
#f
(if (list? (car lst2))
(or (and (sublist? (car lst1) (car lst2))
(sublist? (cdr lst1) (cdr lst2)))
(sublist? (cdr lst1) lst2))
(if (eq? (car lst1) (car lst2))
(sublist? (cdr lst1) (cdr lst2))
(sublist? (cdr lst1) lst2))))))
(sublist? list1 list2)
Explanation:
This is (not) simply handling all the edge-cases:
- If list2
is null - it is always a sublist of list1
- If we got to the end of list1
and list2
is not yet found - return false
- If (car list2)
is a list - we need to check recursively two cases: if (car list1)
equals to (car list2)
or if (car list2)
is somewhere else in (cdr list1)
- If (car list1)
and (car list2)
are the same - we'll check recursively with the rest of both lists: (cdr lst1)
and (cdr lst2)
This answer was tested here
Upvotes: 0