Ряды Фибоначчи в Ada с использованием рекурсии

#ada

#ada

Вопрос:

В этом коде я пытаюсь написать программу, которая выводит ряды Фибоначчи на основе ввода пользователей (индекс, размер). Затем программа должна распечатать все числа Фибоначчи между Index ..Size. У меня возникли проблемы с написанием рекурсии, которая вычисляет и выводит числа Фибоначчи. Есть предложения?

 with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO, Ada.Unchecked_Deallocation;

procedure Fibonacci is
   type Arr is array (Positive range <>) of Integer;
   type Array_Access is access Arr;
   Size, Index : Positive;
   Variable    : Array_Access;
   procedure Free is new Ada.Unchecked_Deallocation (Arr, Array_Access);

   procedure Recursion (Item : Arr) is                  --Recursion
   begin
      Put_Line
        (Item (Item'First)'Image);                   --Prints out the numbers
      Recursion
        (Item
           (Item'First   Item'First   1 ..
                Item'Last));     --Calculating the Fibonacci numbers
   end Recursion;

begin
   Put ("Welcome to the Fibonacci number series!");
   Put
     ("Enter an initial value and how many Fibonacci numbers you want to print: ");
   Get (Index);
   Get (Size);
   Variable := new Arr (Index .. Size);
   Recursion (Variable);
end Fibonacci;
  

Пример: Введите индекс (начальное значение ряда Фибоначчи): 1
Введите размер (сколько чисел Фибоначчи печатать): 5
Первые 5 чисел Фибоначчи: 1 1 2 3 5

Комментарии:

1. Мне трудно переносить небрежное отсутствие форматирования в вашем коде. Недавно было несколько подобных сообщений, вы все на одном курсе?

Ответ №1:

Из Википедии,

В математике числа Фибоначчи, обычно обозначаемые fn, образуют последовательность, называемую последовательностью Фибоначчи, такую, что каждое число является суммой двух предыдущих, начиная с 0 и 1. То есть
F 0 = 0
F 1 = 1
и
F n = F n — 1 F n — 2

что довольно прямо переводится в

 function Fibonacci (N : Natural) return Natural is
  (case N is
      when 0 => 0,
      when 1 => 1,
      when others => Fibonacci (N - 1)   Fibonacci (N - 2));
  

или, старый стиль,

 function Fibonacci (N : Natural) return Natural is
begin
   if N = 0 then
      return 0;
   elsif N = 1 then
      return 1;
   else
      return Fibonacci (N - 1)   Fibonacci (N - 2);
   end if;
end Fibonacci;
  

Вам нужно выполнять печать вне функции, и, по общему признанию, многократное вычисление более низких результатов неэффективно, но вы не просили об эффективности.

Ответ №2:

Вот как вы можете это сделать (этот код основан на https://rosettacode.org/wiki/Fibonacci_sequence#Recursive )

 with Ada.Text_IO;
with Ada.Integer_Text_IO;

procedure Fibonacci is

   First, Amount: Positive;

   function Fib(P: Positive) return Positive is --Recursion
   begin
      if P <= 2 then
         return 1;
      else
         return Fib(P-1)   Fib(P-2);
      end if;
   end Fib;

begin
   Ada.Text_IO.Put_Line("Welcome to the Fibonacci number series!");
   Ada.Text_IO.Put_Line("Enter an initial value and how many Kombinacci numbers you want to print: ");
   Ada.Integer_Text_IO.Get(First);
   Ada.Integer_Text_IO.Get(Amount);
   for I in First .. First   Amount loop
      Ada.Text_IO.Put("Fibonacci(" amp; Positive'Image(I) amp; " ) = ");
      Ada.Text_IO.Put_Line(Positive'Image(Fib(I)));
   end loop;
end Fibonacci;
  

Комментарии:

1. Я думаю, что это печатает на одно число больше, чем требуется?

2. Да, я виноват. Но также это решение имеет некоторые проблемы с производительностью, особенно при большом начальном числе или очень большом диапазоне. Плюс это работает, только если вы согласны с тем, что числа Фибоначчи начинаются с 1, а не с 0 🙂