2015-06-02 2 views
2

Мне нужно сделать функцию булевой для оценки два списка, например:булева функции подсписка в схеме

(define list1 '((1 2) (4 5) (8 6) (2 8))) 
    (define list2 '((1 2) (8 6))) 

list2 является подсписком list1, и должна вернулась #t, но я не знаю, как сделать это, я стараюсь с помощью этой функции для сравнения двух список

(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)))))) 

помощь :(

+0

возможно дубликат [Есть ли способ проверить, если все элементы списка содержатся в другом списке ракетку?] (Http://stackoverflow.com/questions/29322565/is-there-a- way-to-check-if-all-elements-of-a-list-are-contains-in-another-list) –

ответ

0

Предлагаемое решение:

(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) 

Объяснение:
Это (не) просто обрабатывать все краевые-кейсы:
- Если list2 равно нулю - это всегда подсписка list1 - Если мы добрались до конца list1 и list2 пока не найден - возвращает ложь - Если (car list2) список - мы должны проверить рекурсивно два случая: если (car list1) равно (car list2) или если (car list2) находится где-то в (cdr list1) - Если (car list1) и (car list2) же - мы будем проверять рекурсивно с остальной частью обоих списков: (cdr lst1) и (cdr lst2)

Этот ответ был протестирован here

1

Это sublist? ведет себя как «подмножество?».

; 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. 

эту sublist? ведет себя как "подстроки?"

; 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))))) 
+1

Намного приятнее, чем мой impl. - просто нужно переключить порядок аргументов (он проверяет, является ли list2 подсписком списка1). большой плюс один! :) – alfasin

+0

Одна маленькая проблема, если вы будете '(define list2 '((4 5) (2 8)))' it will return '# t'. Тем не менее, я нашел ту же ошибку в своем имплантате. а также ... – alfasin

+0

Оба '(4 5)' и '(2 8)' являются элементами 'list1', поэтому' # t' - это то, что я ожидаю. – soegaard

Смежные вопросы