Как я могу сгенерировать последовательность Фибоначчи, используя Clojure? - PullRequest
4 голосов
/ 16 апреля 2011
(ns src.helloworld)

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

(fibonacci 0 1)

Я новичок в функциональном программировании и решил начать изучать Clojure, поскольку он очень отличается от C #. Я бы хотел расширить свой кругозор.

Вот ошибка, которую я получаю:

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=>

Математические проблемы никогда не были моей сильной стороной, и я никогда не делал ничего такого, что манипулировало бы числами, подобными этому, поэтому я хотел бы получить любые рекомендации, которые вы можете дать.

Пожалуйста, не дайте мне полное решение.

Желательно, чтобы мне были полезные советы и, возможно, скелет о том, как это должно выглядеть.

Ответы [ 5 ]

4 голосов
/ 16 апреля 2011
(fibonacci (+ b 1) a + b)

Здесь вы вызываете функцию fibonacci с четырьмя аргументами: результат (+ b 1), значение переменной a, функция + и значение переменной b,Поскольку fibonacci было определено только для двух аргументов, вы получаете ошибку, которую вы делаете.

Как только вы исправите это, вы получите ошибку переполнения стека, не видя никакого вывода.Это потому, что вы поставили рекурсивный вызов fibonacci в качестве аргумента println.Поэтому он попытается выполнить рекурсивный вызов перед выполнением println.Поскольку рекурсия бесконечна, вызов println никогда не произойдет.Что вы должны сделать, это сначала напечатать номер, а затем рекурсивно вызвать fibonacci.

После того, как вы сделаете это, программа напечатает много чисел, но стек все равно будет переполнен.Это потому, что clojure не оптимизирует удаленные вызовы хвоста, поэтому даже при использовании хвостовой рекурсии бесконечная рекурсия вызовет переполнение стека.Чтобы предотвратить это, используйте форму recur вместо обычной рекурсии.

В дополнение к этим пунктам ваша программа будет печатать неправильные числа, поскольку вы неправильно реализовали последовательность Фибоначчи.

3 голосов
/ 16 апреля 2011

Вот подсказка о том, почему вы получили ошибку, которую сделали. Вы передали следующие четыре аргумента fibonacci:

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

Это все еще не даст вам работоспособную функцию, и вот один намек на это: что когда-нибудь заставит код перестать выполняться и вернет значение пользователю?

1 голос
/ 17 апреля 2011

Когда я изучал некоторые похожие кодовые каты, я нашел этот сайт очень полезным. Кодировка ката . Они имеют последовательность выдумки как ката желтого пояса. У них также есть решения, опубликованные людьми на нескольких языках (Clojure является одним из них). Таким образом, вы можете сравнить свой ответ с другими и посмотреть, сможете ли вы подобрать какие-либо советы или лучший способ сделать что-либо.

1 голос
/ 16 апреля 2011

Другие ответы объясняют вам ошибку в вызове вашей функции.После исправления этого вы должны изучить использование цикла / рекурсии, который будет выполнять оптимизацию хвостового вызова и, таким образом, не использовать стек для каждого рекурсивного вызова.Хотя было бы довольно сложно привести пример, не предоставив вам всего этого: - / Вот еще один поток, в котором они вычисляют факториал, используя рекурсию в clojure: Factorial

0 голосов
/ 26 мая 2011

Когда вы закончите, вы можете захотеть взглянуть на решение Фибоначчи Кристофа Гранда в Programming Clojure от Stu Halloway.Это самое элегантное решение, которое я видел.Это на странице 137 в 1-м издании (поскольку я слышал, что будет 2-е издание).

...