2016-04-13 17 views
1

私は昨日lispでプログラミングを始めましたので、本当に初心者の間違いをしているのであれば、言い訳をしてください。ベル三角形を使ってベル番号を計算する関数を作成しようとしていますが、再帰三角関数が正しく機能していません。再帰的な三角関数の働きによって、私の再帰的なベル関数も何らかの形で壊れてしまうのではないかと確信しています。私は出力を得る私の三角関数をテストするとき最初の呼び出しでLisp再帰関数が見つからない

:何らかの理由で

(defun bell(l n) 
    (if(< n 1)(list 1)) 
    (if (= n 1)(last l)) 
    (bell (triangle (reverse l) (last l) (list-length l)) (- n 1)) 
) 
(defun triangle(pL nL i) 
    (if(<= i 0) 
     (write "equals zero!") 
     (reverse nL) 
    ) 
    (triangle pL (append (list (+ (nth i pL) (nth i nL))) nL) (- i 1)) 
) 
(write (triangle '(1) '(1) 0)) 


=> 


"equals zero!""equals zero!" 
*** - NTH: -1 is not a non-negative integer 

、関数が最初の呼び出し時に私の基本ケースを満たすべきであるにもかかわらず、二度、私のデバッグコードを印刷しています。

+0

((ステートメントを実行)(他に)この文を実行する)条件(あれば)の場合、ブロックが何かのよう..

を働いていたことに気づきました**は三角形を作成しようとしていますが、OPは実際の問題をここでも確認しています。関数*は予想されるベースケースで終了しません。これは** if **のグループ化によるものです。三角関数の解法はOPを助けるかもしれないが、実際には、なぜ(例えば、(n(n 0)35)42) '' defun foo(n) ** if **の結果は無視されるためです。 –

+0

@JoshuaTaylor私はあなたの意見を得る。 OPは、三角形を解決する方法については求めていないが、なぜ彼はそのエラーを持っているのですか?とにかく、私は、現在のものがエラーを表すものではないので、ポストがより役立ち、より適切なタイトルで簡単に見つけられると思った。 – FrankS101

答えて

3

(if (< n 1) 
    (list 1) 
    (if (= n 1) 
     (last l) 
     (bell #| ... |#))) 

はもっと慣用指揮、およびによく似ていますリストではなく、リットルを、使用するだろう私のデバッグコードを2回印刷していますが、ファンクションは最初の呼び出しでベースケースを満たす必要があります。

ifは、あなたが思っていることを行っていないため、2回印刷されています。最初のifテストが真であるので、はゼロです!が印刷されます。その後、三角関数への再帰呼び出しが呼び出されます。テストは再び真(-1 < = 0)なので、はゼロに等しい!が再度印刷されます。最後に、nthcdr関数が-1で呼び出されるため、エラーが発生します。良いlispデバッガをお勧めします。 Lispworksのものはかなり良いです。

私はあなたのコードで達成しようとしていたことの論理を正直にとらえていません。私は私が書いた:インプリメンテーションを理解する

(defun generate-level (l &optional (result)) 
    "given a list l that represents a triangle level, it generates the next level" 
    (if (null l) result 
    (if (null result) 
     (generate-level l (list (car (last l)))) 
     (generate-level (cdr l) (append result 
             (list (+ (car l) 
               (car (last result))))))))) 


(defun bell (levels &optional (l)) 
    "generate a bell triangle with the number of labels given by the first parameter" 
    (unless (zerop levels) 
     (let ((to-print (if (null l) (list 1) (generate-level l)))) 
      (print to-print) 
      (bell (1- levels) to-print)))) 

もの:

  1. &optional (parameter):このパラメータはオプションであり、デフォルトではnilです。
  2. appendは2つのリストを連結します。私はそれを使ってリストの後ろに挿入します。
  3. let ((to-print x))は、to-printという新しい変数バインディング(ローカル変数)を作成し、xに初期化されます。 (if (= x 1) y z)手段1に等しいxならば、そうでないzyを返す:
  4. は、私はほとんどのCommon Lispでif作品がどのように言及するのを忘れてしまいました。あなたは7つのレベルのベルの三角形を作成するための関数を呼び出す場合

は今:

    1 
       1  2 
       2  3  5 
      5  7 10 15 
     15 20 27 37 52 
    52 67 87 114 151 203 
203 255 322 409 523 674 877 

CL-USER 9 > (bell 7) 

(1) 
(1 2) 
(2 3 5) 
(5 7 10 15) 
(15 20 27 37 52) 
(52 67 87 114 151 203) 
(203 255 322 409 523 674 877) 
NIL 

このように、appropiateパディングでそれを印刷するにはよりよいだろう私はそれを読者の練習として残しました。

+1

コードの軽微なコメント: 'BELL'に不要な' AND'があるようです。 '(WHEN(NOT ...))'の代わりに 'UNLESS'を使い、'(IF(NULL L)...) 'を' LET'バインディングの中で動かしてコードを繰り返す必要があります。おそらく、 'GENERATE-LEVEL'の' IF'のネストの代わりに 'COND'を使うこともできます。 – jkiiski

+0

@jkiiskiありがとう!私はしばらくの間Lispでコード化していないし、私は錆びている。 – FrankS101

+0

@ FrankS101詳細な説明と解決方法をありがとうございます。私は結局、もし条件付きで動作する方法を考え出した。その最初の1つは命令的プログラミングから機能プログラミングへと飛躍したので、私はちょっとばかげていた。私はちょうど全体の三角形の代わりにn番目の鐘の番号が必要でした、そして、これはそれを達成するための最も複雑な方法でしたので、私はこのアプローチを選択しました。 –

2

は効果がありません。彼らは評価され、結果を生み出しますが、あなたはそれを捨てます。ただ、

(defun abc() 
    'a 
    'b 
    'c) 

のようなシンボル aとbを生成し、その後、これでしょう、シンボルCを生成するために C」を評価します B 'と' をを評価します返されます。

(if(<= i 0) 
     (write "equals zero!") ; then 
     (reverse nL)   ; else 
    ) 

の場合、あなたは私がゼロ以下であり、それがある場合、あなたはゼロに等しい印刷し、そうでない場合は、あなた(非破壊的に)nLのリバースかどうかを比較しています結果を破棄します。次に、の三角形を呼び出して関数を終了します。 返信 iがゼロ以下の場合は、反転されたnLを返すことをお勧めします。

(if (<= i 0) 
    (progn 
    (write ...) 
    (reverse nL)) 
    (triangle ...)) 

あなたの他の機能:

(cond 
    ((<= i 0) (write ...) (reverse nL)) 
    (t (triangle ...))) 

ます。また、グループにフォームを場合とのprognを使用することができますにようあなたは、複数体の形態を有することができるので、代わりに指揮を使用します同じ問題があります。これらの最初のケースで値を返す場合は、実際に返すフォームを使用する必要があります。例えば:何らかの理由で

(cond 
    ((< n 1) (list 1)) 
    ((= n 1) (last list)) 
    (t (bell #| ... |#))) 
-1

ありがとうございます。私は結局下のコードに着いた。私はOPしばらくので、私は**タイトルに編集をロールバック

(defun bell(l n) 
    (if (< n 2)(last l) 
     (bell (triangle l (last l) 0) (- n 1)) 
    ) 
) 
(defun triangle(pL nL i) 
    (if(= i (list-length pL)) nL 
     (triangle pL (append nL (list (+ (nth i pL) (nth i nL)))) (+ i 1)) 
    ) 
) 
(write (bell (list 1) 10)) 
関連する問題