[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bep] learning lisp: while



 r高橋です。

Reply TAKAHASHI Naoto <ntakahas@...>'s message:

} (while 条件 S式1 S式2 ...)
} 
} は、「条件」が成立している間、「S式1」「S式2」...をくり返し実行します。
} 簡単な類を示します。
} 
} (defun sigma (n)
}   (let ((i 1) (s 0))
}     (while (<= i n)
}       (setq s (+ s i))
}       (setq i (1+ i)))
}     s))

 n を 4 にして実際の数字を入れてみました。

(defun sigma (n)
(let ((i 1) (s 0)) ; i=1 s=0
----
(while (<= i n) ; 1<=4
(setq s (+ s i)) ; s=0+1=1
(setq i (1+ i))) ; i=i+1=1+1=2

(while (<= i n) ; 2<=4
(setq s (+ s i)) ; s=1+2=3
(setq i (1+ i))) ; i=i+1=2+1=3

(while (<= i n) ; 3<=4
(setq s (+ s i)) ; s=3+3=6
(setq i (1+ i))) ; i=i+1=3+1=4

(while (<= i n) ; 4<=4
(setq s (+ s i)) ; s=6+4=10
(setq i (1+ i))) ; i=i+1=4+1=5

(while (<= i n) ; 5<=4
----
s)) ; 10

} これは1からnまでの数をすべて足すプログラムです。前にやった fact もこれ
} と同じような形に書き直せますので、時間があったらチャレンジしてみて下さ
} い。また反対に、上の sigma を while でなく再帰で書くこともできます。

 sはこれまでの結果を覚えていてくれて、iは1から順に1ずつ増えて行く役割な
んですね……?

 fact をwhile で書くと、

(defun fact (n)
  (setq s 1)
  (when (and (integerp n) (>= n 1))
    (while (>= n 1)
      (setq s (* s n))
      (setq n (- n 1)))
    s))

でしょうか? (setq s 1) が最初思いつけなくて、ちょっと悩みました。

 sigma を再帰で書くと、

(defun sigma (n)
  (when (and (integerp n) (>= n 1))
    (if (= n 1)
        1
      (+ n (sigma (- n 1))))))

ですか?

} while でよくやる失敗は、ループ変数の更新を忘れて無限ループしてしまうこ
} とです。上の例では (setq i (1+ i)) を入れ忘れるのがこれに当たります。

 sigma の場合は、(setq i (1+ i)) がないと、プログラムそのものの意味もな
くなってしまいますよね(1ずつ増える数字が足せなくなる)?


**-***-***-***-***-***-***-***-***-***-***-***-**
           Reiko TAKAHASHI  (高橋玲子)
         E-mail:  HFC03614@...
         ICQ UIN: 85924121  (Twinkle)
**-***-***-***-***-***-***-***-***-***-***-***-**