Содержание
Задача: 1) составьте программу для вычисления и вывода n
-го числа Фибоначчи с использованием рекурсии; 2) составьте программу для вычисления и вывода n
-го числа Фибоначчи с использованием рекурсии; 3) рассчитайте время, затрачиваемое каждым из методов расчёта на получение числа Фибоначчи.
Решение лабораторной работы
Рекурсивный метод расчёта чисел Фибоначчи
Числа Фибоначчи — элементы числовой последовательности в которой первые два числа равны 0 и 1, а каждое последующее число равно сумме двух предыдущих чисел, т.е. последовательность следующая 0, 1, 1, 2, 3, 5, 8....
. Общая формула для расчёта n-го члена последовательности выглядит следующим образом: F(0) = 0; F(1) = 1, F(n) = F(n-1)+F(n-2). В принципе, уже, исходя из представленной формулы мы можем составить рекурсивный метод в котором условием выхода из рекурсии (базовым сценарием) будет условие:
if ((n == 0) || (n == 1)) return n;
Сам рекурсивный метод для расчёта числа Фибоначчи будет выглядеть следующим образом:
static long Fib(int n) { if ((n == 0) || (n == 1)) return n; return Fib(n - 1) + Fib(n - 2); }
Исходный код программы:
namespace ConsoleApp1 { internal class Program { static long Fib(int n) { if ((n == 0) || (n == 1)) return n; return Fib(n - 1) + Fib(n - 2); } static void Main(string[] args) { Console.WriteLine(Fib(0)); Console.WriteLine(Fib(1)); Console.WriteLine(Fib(2)); Console.WriteLine(Fib(3)); Console.WriteLine(Fib(4)); Console.WriteLine(Fib(5)); } } }
Проверим работу программы. В результате мы должны получить последовательность: 0, 1, 1, 2, 3, 5
. Результат:
1
1
2
3
5
Верный результат получен. Переходим ко второй части задания.
Метод расчёта чисел Фибоначчи без использования рекурсии
Этот метод будет немного тяжелее в плане прочтения, но, тем не менее, тоже относительно простой. Для расчёта используем цикл for
:
static long Fib2(int n) { if (n == 0) return 0; int prev = 0; int next = 1; for (int i = 1; i < n; i++) { int sum = prev + next; prev = next; next = sum; } return next; }
Проверим результат расчёта, например, 10-го числа с использованием этого метода и рекурсивного:
static void Main(string[] args) { Console.WriteLine($"Результат рекурсивного метода: {Fib(10)}"); Console.WriteLine($"Результат метода с циклом: {Fib2(10)}"); }
Вывод в консоли
Результат метода с циклом: 55
Расчет времени, затрачиваемого каждым из методов расчёта на получение числа Фибоначчи
Для расчёта времени, затрачиваемого на выполнение метода воспользуемся классом Stopwatch, который располагается в пространстве имен System.Diagnostics. Подключаем это пространство имен в свой проект:
using System.Diagnostics;
Дописываем код метода Main следующим образом:
static void Main(string[] args) { Stopwatch sw = Stopwatch.StartNew(); //запускаем таймер long result = Fib(40); //рассчитываем 40-е число sw.Stop(); //останавливаем таймер Console.WriteLine($"Результат рекурсивного метода: {result}. Время выполнения операции {sw.ElapsedTicks} тактов"); sw.Restart(); //перезапускаем таймер result = Fib2(40); //рассчитываем 40-е число sw.Stop(); //останавливаем таймер Console.WriteLine($"Результат метода с циклом: {result}. Время выполнения операции {sw.ElapsedTicks} тактов"); }
Результат выполнения:
Результат метода с циклом: 102334155. Время выполнения операции 851 тактов
Итого
В этой лабораторной работе мы закрепили свои знания о работе рекурсивных методов в C#, а также наглядно продемонстрировали различия в скорости работы рекурсивных методов и методов, не использующих рекурсию.