1

今日はクラスでループについて説明しましたが、やらなければならないことがいくつかあります。簡単に言えば、再帰の代わりにループを使用してリストを作成する必要があります。私はここでつまずきにいるようです。この例では、単純なカウントダウンを行う必要があります。この関数は引数を取り、最初の引数以下のすべての正の整数のリストを返します。(カウントダウン 5) => (5 4 3 2 1)

なんらかの理由でループを取得するのに苦労しています。私たちが話したのは、Loop、Do、Dotimes、および Dolist です。私はこれをいくつかのループで試しましたが、常に同様の結果になります。

(defun countdown (num)
  (cond ((= num 0) nil)
        (T  (let* ((list nil))
              (loop
                (if (= num 0) (return list)
                    (setf list (cons list num)))
                (setf num (- num 1)))))))

私の出力は次のように表示されます。

(((((NIL . 5) . 4) . 3) . 2) .1)

更新:問題を解決しました。どうやら の順序を逆にする必要があったようで、 のconsnumに来listます。誰かがこれを説明したいですか?リストを最初に置いてから、2番目に置いたものが最後に追加されると思いました。少なくとも、私はこれまで問題なく使用してきました。

4

3 に答える 3

4

引数を逆にするcons(およびその理由)

あなたは答えを書きました(それは、より多くの情報を求めているので、おそらくコメントだったはずです):

問題を解決しました。どうやらコンスの順序を逆にする必要があったため、リストの前に num が来ます。誰かがこれを説明したいですか?リストを最初に置いてから、2番目に置いたものが最後に追加されると思いました。少なくとも、私はこれまで問題なく使用してきました。

この関数は、HyperSpec に明確に文書化されています: Function CONS。ドキュメントの例は、例えば、

(cons 1 (cons 2 (cons 3 (cons 4 nil)))) =>  (1 2 3 4)
(cons 'a (cons 'b (cons 'c '()))) =>  (A B C)
(cons 'a '(b c d)) =>  (A B C D)

そしてメモさえ

object-2 がリストの場合、cons はそれに似ているが object-1 が先頭に追加された新しいリストを生成すると考えることができます。

以下を含む 14.1.2 Conses as Listsも読むと役立つ場合があります。

リストは、各コンスの car がリストの要素であるコンスのチェーンであり、各コンスの cdr は、チェーン内の次のリンクまたは終端アトムのいずれかです。

についてloop

ここでの回答の多くは、ループ形式に特別な反復言語が含まれていることを指摘しています。それは本当ですが、あなたがそれを使用している方法で使用することもできます. その方法は単純なループと呼ばれます:

6.1.1.1.1 単純なループ

単純なループ フォームは、複合フォームのみを含む本体を持つフォームです。各フォームは、左から右に順番に評価されます。最後のフォームが評価されると、最初のフォームが再度評価され、というように終わりのないサイクルで繰り返されます。単純なループ形式は、nil という名前の暗黙のブロックを確立します。単純なループの実行は、(return または return-from を使用して) 明示的に制御を暗黙のブロックに転送するか、ブロック外の出口点に (たとえば、throw、go、または return-from を使用して) 転送することによって終了できます。

単純なループは、ループが提供するより優れた機能を使用するループほど一般的ではないかもしれませんが、クラスでこれについて説明しただけでは、まだ理解していない可能性があります。ただし、他の回答はいくつかの良い例を提供します。

于 2014-09-17T11:46:13.973 に答える
2

Common Lisp loopについて話す場合、カウントダウンは次のようになります。

(defun countdown (from-number)
  (loop :for x :from from-number :downto 1 :collect x)) 

CL-USER> (countdown 10) 
(10 9 8 7 6 5 4 3 2 1)
于 2014-09-17T04:30:59.890 に答える
1

loop実際には Lisp のようには見えない独自の「専用言語」を持つを使用すると、次のようになります。

(defun countdown (n)
  (loop
    for i from n downto 1
    collect i))

または使用do

(defun countdown (n)
  (do ((i 1 (1+ i)) 
       (res nil (cons i res)))
      ((> i n) res)))

こちら、特に第 7 章と第 22 章を参照してください。

于 2014-09-17T04:31:24.823 に答える