Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

End Function




Private Function Factorial(ByVal N As Integer) As Long

Индукция. Рекурсия

Понятие рекурсии - сложное, но необходимое понятие для программиста.

Здесь мне никуда не уйти от классического примера о факториале. Факториалом целого положительного числа N называется произведение всех целых чисел от 1 до N. Например, факториал пяти равен 1*2*3*4*5, то есть 120. Факториал единицы считается равным 1.

Все понятно. Однако, существует еще один, совершенно ужасный способ определения, что такое факториал. Этот способ определения называется индуктивным. Вот он:

"Факториал единицы равен 1. Факториал любого целого положительного числа N, большего единицы, равен числу N, умноженному на факториал числа N-1 ."

Если вам уже все ясно, значит вы - профессор математики. Для обычных людей поясню. Возьмем какое-нибудь конкретное N, например, 100. Тогда ужасное определение будет звучать проще: Факториал числа 100 равен числу 100, умноженному на факториал числа 99.

Ну и что? И как же отсюда узнать, чему равен какой-нибудь конкретный факториал, скажем, факториал трех? Будем рассуждать также совершенно чудовищным образом:

 

Смотрю в определение: Факториал трех равен 3 умножить на факториал двух. Не знаю, чему равен факториал двух. Поэтому спускаюсь на ступеньку ниже.

 

Смотрю в определение: Факториал двух равен 2 умножить на факториал единицы. Не знаю, сколько это. Спускаюсь еще на ступеньку.

 

Смотрю в определение: Факториал единицы равен 1. Вот, наконец-то - впервые узнал конкретное число. Значит можно подниматься обратно.

 

Поднимаюсь на одну ступеньку. Факториал двух равен 2 умножить на 1, то есть 2. Хорошо.

 

Поднимаюсь еще на ступеньку. Факториал трех равен 3 умножить на 2, то есть 6. Задача решена!

 

Рассуждая таким образом, можно вычислить факториал любого числа. Этот способ рассуждения называется рекурсивным.

:

Какое отношение все это имеет к компьютерам? Дело в том, что рекурсивный способ рассуждений реализован во многих языках программирования, в том числе - и в Visual Basic. Значит, этим языкам должен быть понятен и индуктивный способ написания программ.

Обозначим кратко факториал числа N, как Factorial(N), и снова повторим наш индуктивный способ объяснения:

"Если N=1, то Factorial(N) = 1.

Если N>1, то Factorial(N) вычисляется умножением N на Factorial(N-1) ."

 

В соответствии с этим объяснением напишем на Visual Basic функцию Factorial для вычисления факториала:

If N = 1 Then Factorial = 1

If N > 1 Then Factorial = N * Factorial(N - 1)

 

Private Sub Command1_Click()

Debug.Print Factorial(3)

End Sub

Что самое удивительное - функция работает! Несмотря на то, что в программе нигде не употребляется оператор цикла. Вся соль программы в том, что функция Factorial вместо этого включает в себя вызов самой себя - Factorial(N-1).

:

Что же происходит в компьютере во время выполнения программы? Механизм происходящего в точности соответствует нашему путешествию по ступенькам:

 

Все начинается с того, что мы щелкаем по кнопке и Visual Basic пробует выполнить строку Debug.Print Factorial(3). Для этого он вызывает функцию Factorial. Выполнение подпрограммы начинается с того, что в памяти отводится место для всех параметров и локальных переменных, а значит и для нашего параметра N. Затем число 3 подставляется на место параметра N, то есть в память в ячейку N посылается 3. Затем выполняется тело функции. Так как 3>1, то Visual Basic пытается выполнить умножение 3* Factorial(3-1) и сталкивается с необходимостью знать значение функции Factorial(2), для чего вызывает ее, то есть отправляется ее выполнять, недовыполнив Factorial(3), но предварительно запомнив, куда возвращаться.

 

Спускаюсь на ступеньку ниже. В соседнем месте памяти отводится место для N. Это уже другое N, путать их нельзя! В эту ячейку N посылается 2. Затем выполняется тело функции. Пусть вас не смущает, что Visual Basic второй раз выполняет тело функции, не закончив его выполнять в первый раз. Так как 2>1, то Visual Basic пытается выполнить умножение 2* Factorial(2-1) и сталкивается с необходимостью знать значение функции Factorial(1), для чего вызывает ее.

 

Спускаюсь еще на ступеньку. В соседнем месте памяти отводится место еще для одного N. В эту ячейку N посылается 1. Затем выполняется тело функции. Так как 1=1, то Visual Basic вычисляет Factorial=1. Вот - впервые конкретное число. Затем Visual Basic пытается выполнить следующую строку if N>1 then Factorial = N* Factorial(N-1). Поскольку нельзя сказать, что 1>1, то строка не выполняется и выполнение тела функции закончено. Значит можно подниматься.

 

Поднимаюсь на одну ступеньку. Visual Basic возвращается внутрь тела функции (той, где N=2) и успешно выполняет умножение - Factorial =2*1=2.

 

Поднимаюсь еще на ступеньку. Visual Basic возвращается внутрь тела функции (той, где N=3) и успешно выполняет умножение - Factorial =3*2=6. Задача решена.

 

Итак, рекурсией в программировании называется вызов подпрограммы из тела самой подпрограммы.

Чем хорош рекурсивный стиль программирования? В нашей программе о факториале мы как бы и не программировали вовсе, а просто обяснили компьютеру, что такое факториал. Как бы перешли на новый уровень общения с компьютером: вместо программирования - постановка задачи.

Чем плох рекурсивный стиль программирования? Если мы для решения той же задачи напишем программу не с рекурсией, а с обычным циклом, то такая программа будет выполняться быстрее и потребует меньше памяти.

 

Задание 131: Напишите рекурсивную функцию fib для вычисления чисел Фибоначчи.




Поделиться с друзьями:


Дата добавления: 2014-12-23; Просмотров: 535; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.011 сек.