1

累積とフォルダーを学習していますが、コードに何か問題があります。すべてのリストの要素を比較したいのですが、foldr は最初と 2 番目の要素のみを使用します。これが私のコードです:

(define accum?
  (lambda (list1 pre?)
  (foldr (lambda (x y) 
               (if (pre? (car list1) (cadr list1)) #t #f))
         #f
         list1)))

(accum? '(1 2 3 4) <) --> #t
(accum? '(3 2 3 4) <) --> #f
(accum? '(1 2 5 4) <) --> #t (should be #f)
(accum? '(5 7 2 3) <) --> #t (should be #f)

どこが間違っているか分かりますか?ちなみに、if --> (if <...> #t #f)? は使わずに (pre? (car list1) (cadr list1)) だけ使ったほうがいいです。

4

2 に答える 2

2

applyこの問題は、比較演算子が可変数の引数を受け取るという事実を使用して、より簡単に解決できます。

(apply < '(1 2 3 4))
=> #t

(apply < '(1 2 5 4))
=> #f

アップデート

特にこの問題については、ジョブに適したツールではありません(ただし、実証foldrしたように不可能ではありません)-リストがトラバースされている間、「蓄積」される値はありません。リストは順序付けされています指定された述語に対してかどうか。

コメントから、プロシージャが正確に 2 つのパラメータを受け取るpre?任意のプロシージャになる可能性があることを理解しています。lambda

考えられる解決策は、連続する要素のすべてのペアのすべてのリストを作成し、述語がそれらすべてに当てはまるかどうかを確認することです。最後の要素には対応するペアがないことに注意してください。そのため、ペアのリストから除外する必要があります。そのために、zip2 つの入力リストが与えられた場合に、リストの長さが異なる可能性があるという事実を考慮して、ペアのリストを作成する特別な手順を定義します。

(define (zip lst1 lst2)
  (if (or (null? lst1) (null? lst2))
      '()
      (cons (list (car lst1) (car lst2))
            (zip (cdr lst1) (cdr lst2)))))

(zip '(1 2 3) '(2 3))
=> '((1 2) (2 3))

すべてをまとめると、元の問題は次のように解決できます。

(define (accum? lst pre?)
  (andmap (lambda (tuple)
            (pre? (car tuple) (cadr tuple)))
          (zip lst (cdr lst))))

空のリストでは機能しないことに注意してください。ただし、これに特別なケースを追加するのは簡単です。これで、任意の比較を行うことができますlambdas:

(accum? '(1 2 3) (lambda (a b) (= a (- b 1))))
=> #t
于 2012-12-01T18:03:35.390 に答える
0

(car list1)最初と 2 番目の要素を取得するandを明示的に使用するため、最初と 2 番目の要素のみを使用しています(cadr list1)

x実際にandを使用していないときはy、引数がラムダに渡されることに注意してください。これは、あなたが何か間違ったことをしているという確かな兆候です。

PS: これはあなたの問題とは関係ありませんが、書く(if condition #t #f)ことはただ書くこととほとんど同じですcondition。そうifです、それは何の役にも立たないので、除外する方が良いです。

于 2012-12-01T16:44:08.220 に答える