10
(do ((n 0 (1+ n))
     (cur 0 next)
     (next 1 (+ cur next)))
    ((= 10 n) cur)))

これは、キーワード「do」に関する Lisp 教科書の例です。

「do」基本テンプレートは次のとおりです。

(do (variable-definitions*)
    (end-test-form result-form*)
 statement*)

しかし、この例では、どの部分がどれであるかはわかりません。また、真ん中の 2 行は何をしますか?

ありがとうございました!

4

4 に答える 4

29
(do ((n 0 (1+ n))  ;declares n, initially 0, n+1 each subsequent iteration)
     (cur 0 next)   ;declares cur, initially 0, then old value of next
     (next 1 (+ cur next))) ;declares next, initially 1, then the sum of (the old) cur and next
    ((= 10 n) ;end condition (ends when n = 10)
     cur)    ; return value
  ;empty body
  )

Cライクなコードに変換

for(n=0, cur=0, next=1 ;
    !(n == 10) ;
    n=old_n+1, cur=old_next, next = old_cur + old_next)
{
    //do nothing 
    old_n = n;
    old_cur = cur;
    old_next = next;
}
return cur;

ちなみに、このコードが 10 番目のフィボナッチ数を返すことがわかるはずです。


オプションの EBNF/正式な構文:

Hyperspecに従った構文は次のとおりです。

(do ({var | (var [init-form [step-form]])}*) 
    (end-test-form result-form*) 
    declaration* 
    {tag | statement}*)

これを理解するには、EBNFと Hyperspec の大きなチャンクに関する知識が必要です。

于 2012-04-17T06:04:18.100 に答える
14

あなたの良いインデントは、どの部分がどの部分であるかを明確に示しています:

(do ((n 0 (1+ n))
    ^(cur 0 next)
    |(next 1 (+ cur next)))
    |
    +-- first argument of do

    ((= 10 n) cur)))
    ^
    |
    +-- start of second argument of do

ほら、きれいに並んでいて、内側の素材がへこんでいます。

   ((n 0 (1+ n))
    (cur 0 next)
    (next 1 (+ cur next)))
    ^
    |
    +- inner material of argument: three forms which are
       indented by 1 character and aligned together.

そこには 3 番目の引数がありませdoん。ステートメントの本体はありません (空のループ)。

于 2012-04-17T19:16:56.077 に答える
0
(do ((n 0 (1+ n))
     (cur 0 next)
     (next 1 (+ cur next)))
    ((= 10 n) cur))

do には 3 つの部分があります。

  1. 変数
  2. 終了条件

この特定の例では、ボディはありません。すべての実際の作業は 1. と 2. によって行われます。最初に 3 つの変数を設定し、初期値とステップ フォームを指定します。たとえばn、0 に設定すると、反復ごとにさらにステップし(1+ n)ます。n

終了条件は((= n 10) cur): n10 に等しいときです。その後、この式curの戻り値全体として を返します。do

これらすべてを組み合わせると、このdo例では 1 から 10 までの合計が 55 になります。

于 2012-04-17T06:05:57.443 に答える