2016-05-18 8 views
0

この関数をビルドして、リストのすべての "var"が数字かどうかを調べます。 私はlisp - すべてのリストが数字であるかどうかを確認するには

(defun check6 (list) 
(if (null list) 'TRUE) 
(if (not (numberp(first list))) nil) 
(check6 (rest list))) 

を実行しようとしましたしかし、何これは、常に私は、スタックオーバーフローを取得します。

どうしますか?

+2

なぜですか?あなたは再帰的に何百回も呼び出しています。あなたは何を期待しますか? –

答えて

10

スタックオーバーフローが、それらが消費され機能の体の残りの部分を実行するためにを継続されていない値を生成するようにあなたは、いくつかの無関係なifを持っているという事実にあります。つまり、check6は決して終了せず、オーバーフローを引き起こします。

あなたは自動的にコードの行を揃える適切なエディタでコードを貼り付ける場合は、編集者は、このアライメントを生成することを発見することができます:

(defun check6 (list) 
    (if (null list) 
     'TRUE)    ; only one branch, no else branch, continue to the next form 
    (if (not (numberp(first list))) 
     nil)    ; again only one branch, continue to the next form 
    (check6 (rest list))) ; infinite loop 

あなたはif特別な演算子を使用したい場合は、

(defun check6 (list) 
    (if (null list) 
     t 
     (if (not (numberp (first list))) 
      nil 
      (check6 (rest list))))) 

しかし、Common Lispのは、はるかを持っている:それは条件が真であるとき、それは(再び適切に位置合わせして)このように偽の、とすべき巣の形のときのための2例を、持っていることを覚えておいてください詐欺のための便利な構文catenating条件、cond:最後に

(defun check6 (list) 
    (cond ((null list) t) 
     ((not (numberp (first list))) nil) 
     (t (check6 (rest list))))) 

は、イテレーションのいずれかを使用して、あなたの問題を解決するために、他の方法があることに注意してください。

(defun check6 (list) 
    (loop for element in list always (numberp element))) 

または高レベルの機能を持つ、より一層簡潔な方法で:

(defun check6 (list) 
    (every #'numberp list)) 
0

あなたは間違いなく、レンゾの機能を書いていますが、あなたのコードはトンから返すことでパッチを適用することができ、さまざまな方法をよく見てとるべき彼は早く機能します:

(defun check6 (list) 
    (if (null list) (return-from check6 'TRUE)) 
    (if (not (numberp(first list))) (return-from check6 nil)) 
    (check6 (rest list))) 
+0

真実ですが、非常に "unlispy" –

0

関数は決して終了しないので、スタックオーバーフローが発生します。

Lispの関数の結果は、関数本体の最後の式の値です。
あなたの場合は(check6 (rest list))です。

私はあなたが、これは(完全に架空の言語で)のようなものが書き込まれることがありますいくつかの他の言語、考えていることを疑う:

bool check6(List list) 
{ 
    if (list.empty()) 
     return true; 
    if (!isNumber(list.head())) 
     return false; 
    return check6(list.tail()); 
} 

が、あなたの条件文は、関数から、その結果を返しません。 ;あなたがそれらで何もしていないので、結果はただ破棄されます。上記の架空の言語で

、あなたの関数は、おそらく間違って起こっているのかを見ることができます

bool check6(List list) 
{ 
    if (list.empty()) 
     true; 
    if (!isNumber(list.head())) 
     false; 
    return check6(list.tail()); 
} 

だろう。

私は個人的に、論理的な表現に比べて従うのが難しい複数の条件を見つけます。リストには、すべての数字であるときは、条件を書き留めた場合

は:数リストが空である

  • 、または
    • そのヘッドれる
    • その尾が全てです数字

あなたは高階関数と知り合いいったんしかし、あなたはおそらく

(defun check6 (list) 
    (every #'numberp list)) 

を書くことになるかもしれない架空の言語で

(defun check6 (list) 
    (or (null list) 
     (and (numberp (first list)) 
      (check6 (rest list))))) 

bool check6(List list) 
{ 
    return list.empty() || (isNumber(list.head()) && check6(list.tail())); 
} 

を:それは、Lispに翻訳するのは簡単です最もLisp-yの解決策になります。

関連する問題