4
(ns src.helloworld)

(defn fibonacci[a b] (println a b (fibonacci (+ b 1) a + b)))

(fibonacci 0 1)

関数型プログラミングは初めてで、C# とは大きく異なる Clojure の学習を開始することにしました。視野を広げたい。

エラーは次のとおりです。

Clojure 1.2.0
java.lang.IllegalArgumentException:
Wrong number of args (4) passed to:
helloworld$fibonacci
(helloworld.clj:0) 1:1 user=>
#<Namespace src.helloworld> 1:2 src.helloworld=>

数学の問題は私の得意分野ではありませんでしたし、このような数字を操作するものを実際に作成したこともありませんでした.

解決策全体を私に教えないでください。

できれば、いくつかの良いヒントと、それがどのように見えるべきかのスケルトンが欲しいです。

4

5 に答える 5

4
(fibonacci (+ b 1) a + b)

ここではfibonacci、4 つの引数を指定して関数を呼び出しています: の結果(+ b 1)、変数の値a、関数+、および変数の値b。は 2 つの引数のみを受け取るように定義されているためfibonacci、エラーが発生します。

これを修正すると、出力が表示されずにスタック オーバーフロー エラーが発生します。これは、 へfibonacciの引数としてへの再帰呼び出しを配置し​​たためですprintln。そのため、実行する前に再帰呼び出しを実行しようとしprintlnます。再帰は無限であるため、 への呼び出しprintlnは発生しません。あなたがすべきことは、最初に番号を出力してから、fibonacci再帰的に呼び出すことです。

これを行うと、プログラムは多くの数値を出力しますが、スタックは最終的にオーバーフローします。これは、clojure が末尾呼び出しを最適化しないためです。そのため、末尾再帰を使用している場合でも、無限再帰によってスタック オーバーフローが発生します。これを防ぐrecurには、通常の再帰の代わりにフォームを使用します。

これらの点に加えて、フィボナッチ数列を間違って実装したため、プログラムは間違った数値を出力します。

于 2011-04-16T19:08:17.063 に答える
3

エラーが発生した理由についてのヒントを次に示します。次の 4 つの引数を に渡しましたfibonacci

  • (+ b 1)
  • a
  • +
  • b.

それでも機能する関数は得られません。これに関するヒントが 1 つあります。コードの実行が停止し、ユーザーに値が返される原因は何でしょうか?

于 2011-04-16T19:09:26.060 に答える
1

他の回答は、関数呼び出しのエラーを説明しています。テールコールの最適化を行い、再帰呼び出しごとにスタックを使用しない loop/recur の使用を検討する必要があることを修正した後。ただし、すべてを説明せずに例を示すのはかなり難しいでしょう:-/ clojureで再帰を使用して階乗を計算する別のスレッドを次に示します: Factorial

于 2011-04-16T19:14:27.030 に答える
1

似たようなコードの型をいくつか学んでいたとき、このサイトがとても役に立ちました。 コーディング型。彼らは黄帯の形としてフィブシーケンスを持っています. また、複数の言語の人々から投稿されたソリューションもあります (Clojure はその 1 つです)。こうすることで、自分の回答を他の回答者と比較して、ヒントやより良い方法を見つけることができるかどうかを確認できます。

于 2011-04-16T20:05:06.643 に答える
0

完了したら、Stu Halloway によるProgramming Clojureで Christophe Grand の Fibonacci ソリューションを見たいと思うかもしれません。これは私が見た中で最もエレガントなソリューションです。初版の 137 ページにあります (第 2 版が出ると聞いたので)。

于 2011-05-26T05:44:25.400 に答える