4

3を超える数値のリスト内の要素の数を列挙する再帰LISP関数が必要です。lets、loops、またはwhileを使用することは許可されておらず、基本的なCAR、CDR、SETQ、COND、CONS、APPEND、PROGNのみを使用できます。 、リスト..。

これは、この関数での私の試みです。

(defun foo (lst) 
  (COND ((null lst) lst) 
    (T (IF (> (CAR lst) 3) 
      (1+ (foo (CDR lst)))
      (foo (CDR lst)) ) ) ) )

関数呼び出し:

(foo '(0 1 2 3 4 5 6))
4

3 に答える 3

5

あなたのコードはかなり正しいものに近いですが、基本的な場合の小さな間違いです:

空のリストの場合は、空のリストを返します。したがって、リストがある場合は、空のリストの(6)6を追加しますfoo。これは空のリストです。リストに番号を追加できないため、これは機能しません。

空のときの代わりにfooリターンを作成することで簡単に修正できます。0lstlst

スタイルノートとして:ミキシングcondifこのように、少し冗長に見えます。cond代わりに、次のように記述します。

(defun foo (lst) 
  (cond
    ((null lst)
      0)
    ((> (car lst) 3) 
      (1+ (foo (cdr lst))))
    (T
      (foo (cdr lst)))))
于 2010-11-18T22:44:59.323 に答える
5

いくつかの文体のポイント:

  • 一部のLispビルトインを大文字にする必要はありません。もう1958年ではありません!
  • しかし、ビルトインを大文字にする場合DEFUN、どうしてNULLですか?
  • の最後のブランチのif内側にありますcond。これは冗長です。cond条件をテストすることが目的なので、使ってみませんか?
  • そのように閉じ括弧の間隔を空ける必要はありません。最近は括弧を数える人は誰もいません。括弧が一致するエディターがあります。
  • lstLispには関数と値に別々の名前空間があるため、組み込み関数との競合を避けるために引数を呼び出す必要はありませんlist

これを実際にプログラミングしている場合は、もちろん次を使用しますcount-if

(count-if #'(lambda (x) (> x 3)) '(0 1 2 3 4 5 6))
    ==> 3
于 2010-11-18T22:55:44.143 に答える
0

再帰呼び出しの複製で1つの節約ができます。

(defun foo (l)
  (if (null l) 0               ; if list is empty, return 0
    (+ (if (> (car l) 3) 1 0)  ; else +1 if condition is satisfactory
      (foo (cdr l)))))         ; plus the result from the rest
于 2018-09-11T01:11:16.650 に答える