
- •Г.В. Ваныкина, т.О. Сундукова
- •Часть 1. Введение в программирование Тула - 2009
- •Содержание
- •Предисловие
- •Лабораторная работа №1
- •Лабораторная работа №2 Типы данных. Стандартные потоки ввода-вывода данных
- •Лабораторная работа №3 Константы. Стандартные потоки ввода-вывода вещественных данных
- •Лабораторная работа №4 Форматированный ввод-вывод данных
- •Лабораторная работа №5 Присваивание. Арифметические операции
- •Лабораторная работа №6 Логические и поразрядные операции. Операции сравнения и определения размера
- •Лабораторная работа №7 Математические функции. Выражения
- •Математические функции – файл math.H
- •Лабораторная работа №8 Линейные программы. Преобразование типов
- •Лабораторная работа №9 Операторы выбора: оператор условия if
- •Лабораторная работа №10 Решение задач с использование оператора условия if
- •Лабораторная работа №11 Операторы перехода. Операторы выбора: оператор-переключатель switch
- •Лабораторная работа №12 Решение задач с использованием оператора-переключателя switch
- •Лабораторная работа №13 Операторы цикла: оператор цикла с параметром for
- •Лабораторная работа №14 Операторы цикла: оператор цикла с предусловие while
- •Лабораторная работа №15 Операторы цикла: оператор цикла с постусловием do … while
- •Лабораторная работа №16 Решение задач с использованием операторов цикла
- •Лабораторная работа №17 Функции пользователя
- •Лабораторная работа №18 Решение задач методом процедурной абстракции
- •Лабораторная работа №19 Рекурсивные функции
- •Индивидуальные задания Требования к оформлению индивидуальных заданий
- •Задание 1. Линейные программы
- •Задание 2. Задачи на составление логических выражений
- •Задание 3. Условный оператор
- •Задание 4. Цикл с параметром
- •Задание 5. Циклы с условиями
- •Задание 6. Числовые функции
- •Задание 7. Функции
- •Задание 8. Рекурсия
- •Литература
- •Часть 1. Введение в программирования
Лабораторная работа №19 Рекурсивные функции
Цель работы: познакомиться с понятием рекурсивных функций в программировании и научиться применять рекурсивные методы в решении задач на языке C++.
Теоретические сведения
В окружающем нас мире часто можно встретить объекты, обладающие самоподобием. То есть часть большого объекта в чем-то сходна с самим объектом. Например, ветка дерева повторяет форму и характер ветвления, схожие с самим деревом. Приведенные ниже графические объекты также обладают самоподобием. Такие объекты называются рекурсивными.
В языках программирования процедурной парадигмы предусмотрено использование рекурсивных функций в решении задач.
Функция называется рекурсивной, если в своем теле она содержит обращение к самой себе с измененным набором параметров. При этом количество обращений конечно, так как в итоге решение сводится к базовому случаю, когда ответ очевиден.
Пример 1. В арифметической прогрессии найдите an, если известны а1= -2.5, d=0.4, не используя формулу n-го члена прогрессии.
По определению арифметической прогрессии, an= an-1+ d, при этом
an-1= an-2+ d, an-2= an-3+ d,… a2= a1+ d.
Таким образом, нахождение an для номера n сводится к решению аналогичной задачи, но только для номера n-1, что в свою очередь сводится к решению для номера n-2, и так далее, пока не будет достигнут номер 1 (значение а1 дано по условию задачи).
float arifm (int n, float a, float d) {
if (n<1) return 0; // для неположительных номеров
if (n==1) return a; // базовый случай: n=1
return arifm(n-1,a,d)+d; // общий случай
}
Пояснение к примеру.
В рекурсивных функциях несколько раз используется return.В базовом случае возвращается конкретный результат (в примере – значение а), а общий случай предусматривает вызов функцией себя же, но с меняющимися значениями отдельных параметров (в примере изменяется только номер члена последовательности, при этом не меняются разность и первый член прогрессии).
Для решения задач рекурсивными методами разрабатывают следующие этапы, образующие рекурсивную триаду:
параметризация – выделяют параметры, которые используются в решении;
база рекурсии – определяют тривиальный случай, при котором решение очевидно;
декомпозиция – выражают общий случай через подзадачи с измененными параметрами.
Пример 2. Для целого неотрицательного числа n найдите его факториал.
Разработаем рекурсивную триаду.
Параметризация: n – неотрицательное целое число.
База рекурсии: для n=0 факториал равен 1.
Декомпозиция: n!=(n-1)!*n.
long factor (int n) {
if (n<0) return 0; // для отрицательных чисел
if (n==0) return 1; // базовый случай: n=0
return factor(n-1)*n; // общий случай (декомпозиция)
}
Целесообразность применения рекурсии в программировании обусловлена спецификой задач, в постановке которых явно или опосредовано указывается на возможность сведения задачи к подзадачам, аналогичным самой задаче.
Пример 3. Дан прямоугольник, стороны которого выражены натуральными числами. Разрежьте его на минимальное число квадратов с натуральными сторонами.
#include <stdio.h>
int kv(int m,int n);
void main(){
int a,b,k;
printf("Введите стороны прямоугольника->");
scanf("%d%d",&a,&b);
k = kv(a,b);
printf("Прямоугольник со сторонами %d и %d можно
разрезать на %d квадратов",a,b,k);
}
int kv(int m,int n){
if(m==n) return 1;
if(m>n) return 1+kv(m-n,n);
return 1+kv(m,n-m);
}
Задания
Для решения задач разработайте рекурсивные функции
Определите закономерность формирования членов последовательности. Найдите n-ый член последовательности: 1, 1, 2, 3, 5, 8, 13,…
Составьте программу вычисления биномиального коэффициента
для данных неотрицательных целых m, n (
):
.Решите задачу двумя способами: 1 – используйте функцию вычисления факториала; 2 – выразите вычисление через
.
Дано натуральное число, кратное 3. Получите сумму кубов цифр этого числа, затем сумму кубов цифр получившегося числа и т.д. Проверьте на нескольких примерах, действительно ли в конечном итоге получится 153.
Домашние задания
Определите закономерность формирования членов последовательности. Найдите n-ый член последовательности: 1, 1, 2, 9, 737, …
Исполнитель умеет выполнять два действия: «+1», «*2». Составьте программу получения из числа 1 числа 100 за наименьшее количество операций.
Найдите наибольший общий делитель двух натуральных чисел с помощью алгоритма Евклида.