Scheme,检查两个列表中的任何内容是否相同

时间:2013-05-22 13:23:12

标签: list scheme procedure

如果两个列表相同,是否可以相互检查两个列表?

(核对清单'(嘿饼干猴)'(苹果披萨饼干)==> #t

我试过像

这样的东西
(define (check-list list element)
  (let ((x list))
  (cond ((null? x) #f)
        ((eq? (car x) (car element)) #t)
        (else (check-list (cdr x) element))))
  (check-list list (cdr element)))

我知道这写不正确,但不知道如何解决这个问题。

任何可以帮助我的人?

7 个答案:

答案 0 :(得分:1)

有时,用自然语言制定问题解决方案的过程会有所帮助。让我们稍微简化一下这个问题。

如何检查列表中是否包含一个元素?一种方法是将一个元素与列表中的每个元素进行比较,直到找到它为止 - 在你已经完成的某个地方 - 但不完全。快速草案将是:

(define (member? e lst)
  (cond ((null? lst) #f)       ; empty list doesn't contain e
        (or (eq? e <??>)       ; either the first element is e or
            (member? e <??>))) ; the rest of the list contains e

我们可以利用以前的知识来解决手头的真正问题。我们知道如何在列表中搜索<​​em>一个元素,现在我们需要在另一个列表中的列表中搜索每个元素。

(define (check-list lst1 lst2)
  (if (or (null? lst1) (null? lst2)) #f  ; empty list(s) share no elements
      (or (member? <??> <??>)            ; first element of lst1 in lst2?
          (member? <??> <??>))))         ; rest of lst1 in lst2?

<??>应该用适当的表达式代替,以便选择列表的各个部分。

答案 1 :(得分:1)

与先前的答案类似,但利用逻辑原语:

(define (intersect? list1 list2)
  (and (not (null? list1))
       (or (member     (car list1) list2)
           (intersect? (cdr list1) list2))))

答案 2 :(得分:1)

如果列表是wicket long,你可能想要散列第一个列表,然后迭代第二个列表。这使用R5RS和srfi-69,对于小型列表,你会得到一点开销,但

(require srfi/69); alist->hash-table, hash-table-ref/default 
(define (intersect? list1 list2)
  (let ((hash (alist->hash-table (map (lambda (x) (cons x x)) list2) equal? )))
    (let loop ((list list1))
      (and (not (null? list))
           (or (hash-table-ref/default hash (car list) #f)
               (loop (cdr list)))))))

答案 3 :(得分:0)

您可以使用memq检查第一个列表中的第一个元素是否在第二个列表中,如果不是,则在第一个列表的其余部分中的某些内容位于第二个列表中时递归检查:

(define (check-list list1 list2)
  (cond ((null? list1) #f)
        ((memq (car list1) list2) #t)
        (else (check-list (cdr list1) list2))))

答案 4 :(得分:0)

似乎有点混乱。这里的“大”问题是如何确定两个列表是否共享至少一个共同的元素,让我们为该element-in-common?编写一个过程。在解决此问题之前,我们需要确定单个元素是否属于一个列表,这是check-list应该做的事情(请注意代码check-list中的第二个参数元素,但您将其视为元素的列表。)

您不必编写check-list程序,它已经存在且名为member。有了这些知识,我们就可以解决一个大问题 - 如何确定一个列表中的至少一个元素(让我们称之为lst1)是否在另一个列表中(称为lst2)? / p>

简单:我们使用递归迭代lst1中的每个元素,询问每个元素是否属于lst2。如果lst1中只有一个元素是lst2的成员,则返回#t。如果lst1中的所有元素都不在lst2中,我们会返回#f。像这样:

(define (element-in-common? lst1 lst2)
  (cond (<???>               ; is the first list empty?
         <???>)              ; then there are no elements in common
        ((member <???> lst2) ; is the current element of `lst1` in `lst2`?
         <???>)              ; then there IS an element in common
        (else                ; otherwise
         (element-in-common? <???> lst2)))) ; advance recursion

不要忘记测试您的代码:

(element-in-common? '(hey cookie monkey) '(apple pizza cookie))
=> #t

(element-in-common? '(hey cookie monkey) '(apple pizza pie))
=> #f

答案 5 :(得分:0)

以下是使用高阶函数的答案

在mit-schme

(define (check-list L1 L2)
 (apply boolean/or (map (lambda (x) (member? x L2)) L1)))

答案 6 :(得分:0)

(define remove-item
  (lambda (lst ele)
    (if (null? lst)
        '()
        (if (equal? (car lst) ele)
            (remove-item (cdr lst) ele)
            (cons (car lst)
                  (remove-item (cdr lst) ele))))))