1

2 つのリストに同じものが含まれている場合、2 つのリストを相互にチェックすることはできますか?

(チェックリスト '(ヘイ クッキー モンキー) '(アップル ピザ クッキー) ==> #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)))

これが正しく書かれていないことは知っていますが、この問題に取り組む方法がわかりません。

私を助けることができる人はいますか?

4

7 に答える 7

1

リストがウィケット長の場合、最初のリストをハッシュしてから、2 番目のリストを反復処理することができます。これは srfi-69 で R5RS を使用し、小さなリストの場合は少しオーバーヘッドが発生しますが、

(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)))))))
于 2013-05-28T21:42:36.577 に答える
1

以前の回答に似ていますが、ロジックプリミティブを利用しています:

(define (intersect? list1 list2)
  (and (not (null? list1))
       (or (member     (car list1) list2)
           (intersect? (cdr list1) list2))))
于 2013-05-22T14:17:12.520 に答える
1

自然言語で問題を解決するプロセスを定式化すると役立つ場合があります。問題を少し単純化しましょう。

リストに1 つの要素が含まれているかどうかを確認するにはどうすればよいですか? これを行う 1 つの方法は、その 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

その以前の知識を使用して、目前の実際の問題を解決できます。リスト内の1 つの要素を検索する方法はわかったので、リスト内の各要素を別のリスト内で検索する必要があります。

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

リストの<??>部分を選択するための適切な式で を置換する必要があります。

于 2013-05-22T13:37:51.127 に答える
0

これが高階関数を使った答えです

ミットスキームで

(define (check-list L1 L2)
 (apply boolean/or (map (lambda (x) (member? x L2)) L1)))
于 2013-05-22T23:19:46.933 に答える
0

少し混乱があるようです。ここでの「大きな」問題は、2 つのリストが少なくとも 1 つの要素を共有しているかどうかを判断する方法ですelement-in-common?。この問題に取り組む前に、単一の要素が 1 つのリストに属しているかどうかを判断する必要がありcheck-listます。これがすべきことです (コードでは要素をcheck-list2 番目のパラメーターとして受け取りますが、要素のリストであるかのように扱っていることに注意してください)。 )。

check-listプロシージャを記述する必要はありません。すでに存在し、呼び出されていmemberます。その知識があれば、大きな問題を解決できます。つまり、あるリスト ( としましょう) の要素の少なくとも 1 つがlst1別のリスト ( と呼びlst2ます) にあるかどうかを判断するにはどうすればよいでしょうか?

簡単:lst1再帰を使用して各要素を反復処理し、各要素が に属しているかどうかを尋ねlst2ます。の 1 つの要素だけlst1が のメンバーであるlst2場合、 を返し#tます。の要素が にない場合lst1lst2、 を返し#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
于 2013-05-22T14:05:45.080 に答える
0

を使用memqして、最初のリストの最初の要素が 2 番目のリストにあるかどうかを確認し、そうでない場合は、最初のリストの残りの部分が 2 番目のリストにあるかどうかを再帰的に確認できます。

(define (check-list list1 list2)
  (cond ((null? list1) #f)
        ((memq (car list1) list2) #t)
        (else (check-list (cdr list1) list2))))
于 2013-05-22T13:36:58.570 に答える