2016-09-26 19 views
0

ここにこの関数があります。なぜ動作しないのか分かりません。再帰関数は機能しません。

let rec recSum n = 
    if n <= 0 then 
    0 
    else 
    recSum n*(n+1)/2 
recSum 4 

エラーは発生しません。ただクラッシュします。誰もが間違いを見つけることができますか?私はこれほど長い間主演してきました。

再帰的にする必要があります。あなたたちが指摘したように、nは唯一増加することになるので

let rec recSum n = 
if n > 0 then 
    recSum n*(n+1)/2 
else 
    n 
n 
recSum 4 

は大丈夫そう、私はそれを変更しました。今私はエラー'FS0001:型ユニットがintに一致しないのですか?

+0

達成しようとしていることを明確にすることはできますか?以下に述べるように、これは無限回帰ですので、別の式を実装する必要があります。要件についての詳細がわかっていれば、新しい式を見つけるのに役立ちます。 – EJoshuaS

+1

知られているすべての入力に対して同様の処理が行われるのは、[Collat​​z conjecture](https://en.wikipedia.org/wiki/Collat​​z_conjecture)の中心にある関数です。* half-or-triple-plus-one *。あなたのスタックの限界はわかりませんが、1228の関数呼び出しをスタックすることができれば、1000億までの入力で0に達することができます。 –

答えて

1

終了条件は決して満たされないため、これは無限再帰です。 (私は実際にはスタックオーバーフローの例外がないことに驚いています)。 n = 0のとき終了条件はあるが、すべての再帰呼び出しは、ちょうど1を追加します:n*(n+1)/2

また、あなたは次の再帰呼び出しではなく、

n * recSum (n+1)/2 

のようなものへの引数として乗算を含めることが意味しました(構文が完璧でない場合は私を許してください。私はIDEの前にいません)。

おそらく、あなたは加算の代わりに減算することを意味しましたか?

逃亡のビットとして、終了条件として選択するのは、達成しようとしていることと実装しようとしている式に依存します。多くの人が現在の値から終了条件に「下がる」と考えています。例えば、あなたがフィボナッチ数について話しているならば、ほとんどの人は、これを単に「前の2つのフィボナッチ数の合計」と考えるでしょう(どちらも、以前の2つのフィボナッチ数の合計です。終わりの状態への「ダウン」)。これは完全に正しいです。例えば、5を定義するのは完全に真です! 5 * 4!とします。

また、終了条件から「処理中」と考えることもできます。私はあなたに10の価値を教えてくれるように頼んだら、計算機を使わずに値が何であったのかはほとんど分からないでしょう。しかし、もし私があなたにそれを言ったら、9! 362,880ですか?さて、10を乗算するために10を掛けることは明らかです。明らかに答えは3,628,800でなければなりません。それは事実です、11は何ですか?まあ、明らかに、11 * 3,628,800。だから、私があなたに価値を与えるならば、その値を使ってより多くの価値を "生成"することができます。 9の値を与えられれば、10を得るためにそれを乗算する以外に何もする必要はありません!

実際、あなたの知識があれば、10! = 3,628,800、簡単に9を計算することができます! 3,628,800を10で除算したものです。

いずれにしても、ポイントは同じです:「シーケンス」内の任意の値を指定すると、それらの値に適用してシーケンス内のより多くの値を計算できるというルールがあります。

この意味では、実際には終了条件を、私が推測する並べ替えの「初期条件」と呼ぶことができます。

うまくいけば、それは意味があると思いますが、そうでない場合は、必要に応じていくつか明確にすることがうれしいです。

+0

recSumに渡される値は、再帰によって急激に増加します。おそらく、値が可変型の容量を超え、スタックがオーバーフローする前にある種の割り当てが失敗する可能性があります。 –

+0

@JuanTomasそう、それは可能性のようだ、私は最初に起こったいくつかの他のエラーがあるかどうか疑問に思っていた(またはコンパイラがオーバーフロー例外を防ぐ "無限ループは明らかにスタックオーバーフロー例外を発生させません)。 – EJoshuaS

+0

コードを編集しましたが、もう別のエラーが発生しています。上掲。 – kthonenice

5

問題は、n*(n+1)/2は、再帰で渡される値が常に増加することです。今までにn <= 0を取得する方法はありません。シーケンスが開始されます。

4 -> 10 -> 55 -> etc...

recSumに渡された値がしか増加します。

関連する問題