
Л-4 Орг подпр. Рекурсия.ppt
- Количество слайдов: 68
Основы процедурного программирования. Object Pascal Курс лекций для студентов 1 -го курса факультета Ми. И Лектор Олейников Борис Васильевич
Лекция 4. Инструменты и теоретические основы структурного программирования Содержание Необходимость СП Принципы СП Подпрограмма – основа СП Виды подпрограмм Реализация подпрограмм в Object Pascal Процедуры и функции Механизм параметров Виды параметров и их использование Использование процедур и функций в программе Области действия имен Директивы Рекурсия Виды рекурсии Прямая и косвенная рекурсия в Object Pascal
Необходимость структурного программирования С развитием программного обеспечения (ПО), и появления устойчивой тенденции ко все более увеличивающейся сложности и объема программы одними из основных требований к созданию ПО стали Быстрота создания ПО; Прозрачность ПО; Надежность ПО; Безопасность ПО
Решение Переход из «искусства программирования» на «промышленную основу» Для этого необходимо разработать стили и технологии программирования И таких технологий было создано много ( «сверхувниз» , HIPO, структурное, «Прометей» , Rтехнология и др. ) Многие из них утратили свое значение, другие стали чуть ли не стандартными. В частности, прижилось структурное программирование (стиль, методология структурного программирования) – предложил в 70 -годах Эдсгер Вайба Дейкстра, дополнили Никлаус Вирт и Энтони Хоар
Основная идея (1) 1) Любая программа представляет собой структуру, построенную из трёх типов базовых конструкций: последовательное исполнение — однократное выполнение операций в том порядке, в котором они записаны в тексте программы; ветвление — однократное выполнение одной из двух или более операций, в зависимости от выполнения некоторого заданного условия; цикл — многократное исполнение одной и той же операции до тех пор, пока выполняется некоторое заданное условие (условие продолжения цикла). В программе базовые конструкции могут быть вложены друг в друга произвольным образом, но никаких других средств управления последовательностью выполнения операций не предусматривается.
Основная идея (2) 2) Повторяющиеся фрагменты программы (либо не повторяющиеся, но представляющие собой логически целостные вычислительные блоки) могут оформляться в виде т. н. подпрограмм (процедур или функций). В этом случае в тексте основной программы, вместо помещённого в подпрограмму фрагмента, вставляется инструкция вызова подпрограммы. При выполнении такой инструкции выполняется вызванная подпрограмма, после чего исполнение программы продолжается с инструкции, следующей за командой вызова подпрограммы.
Основная идея (3) 3) Существует 2 основных способа разработки программ ( «снизу-вверх» и «сверху-вниз» ). В структурном Разработка программы ведётся пошагово, методом «сверху вниз» . Сначала пишется текст основной программы, в котором, вместо каждого связного логического фрагмента текста, вставляется вызов подпрограммы, которая будет выполнять этот фрагмент. Вместо кода подпрограмм, в программу вставляются «заглушки» , которые ничего не делают. Полученная программа проверяется и отлаживается последовательность вызовов подпрограмм. После этого подпрограммы-заглушки последовательно заменяются на реально работающие, причём разработка каждой подпрограммы ведётся тем же методом, что и основной программы и может осуществляться другими разработчиками.
Принципы структурного программирования - по Дейкстра (1) 1) Никаких трюков и заумного программирования. Никогда не пользуйтесь сложными методами там, где можно обойтись простыми. 2) Как можно меньше переходов. Без крайней необходимости не используйте оператор перехода goto. 3) Осуществляйте выбор с использованием ifthen-else или case для исключения переходов извне внутрь рассматриваемой структуры.
Принципы структурного программирования - по Дейкстра (2) 4) Применяйте простые циклы, задавая их в явном виде (используя циклы for, while, repeat-until). 5) Применяйте содержательные обозначения для всех имен в программе. 6) Осуществляйте сегментацию программы. Большие программы следует разбивать на логически завершенные сегменты – подпрограммы. В идеальном случае нужно стремиться к тому, чтобы сама программа состояла практически целиком из подпрограмм. Аспекты такого подхода – структурность, экономичность, проектируемость и коллективность (конвеерность) разработки, обозреваемость, надежность. Все это и определяет промышленный подход к разработке программного обеспечения.
Достоинства структурного программирования Структурное программирование позволяет значительно сократить число вариантов построения программы по одной и той же спецификации, что значительно снижает сложность программы и, что ещё важнее, облегчает понимание её другими разработчиками. В структурированных программах логически связанные операторы находятся визуально ближе, а слабо связанные — дальше, что позволяет обходиться без блок-схем и других графических форм изображения алгоритмов (по сути, сама программа является собственной блок-схемой). Сильно упрощается процесс тестирования и отладки структурированных программ.
Подпрограмма Концепция подпрограммы впервые была описана М. Уилксом в 1957 г. И с тех пор получила распространение практически во всех языках программирования. Определение 5. 1. Подпрограмма – это именованная, логически законченная часть программы (т. е. группа операторов языка программирования), которую можно вызывать по имени для выполнения любое количество раз (в том числе и при различных параметрах) из разных мест программы.
Назначение подпрограмм Средство сокращения исходного текста программы; Средство вариантного использования частей (кусков) программы; Средство декомпозиции программы; Основной инструмент структурного программирования; Основное средство коллективной разработки программы
Виды подпрограмм Стандартные или определяемые пользователем; С параметрами или без параметров; Выдающими много значений или одно; Отдельно компилируемыми или нет
Реализация подпрограмм в Object Pascal В языке Object Pascal реализованы все виды подпрограмм Основными из них являются процедуры и функции Процедуры и функции могут быть как стандартные, так и определяемые пользователем, с параметрами и без. Но не могут быть скомпилироваными отдельно от основной программы. Подпрограммы допускающие отдельную компиляцию в Object Pascal реализованы в виде модулей (unit) и динамически подгружаемых библиотек (library), но об этом позже.
Процедуры и функции в Object Pascal Отличие процедур и функций - в реализации, процедуры могут на выходе давать много значений, а функция обычно только одно; - в использовании, функции могут использоваться в выражениях, а процедуры нет; - в описании, для функции необходимо указывать тип, а для процедуры нет.
Объявление и описание процедур и функций Объявляются в своем разделе программы Состоят из заголовка и тела Заголовок имеет вид procedure <имя>(<список параметров>); <директивы>; function <имя>(<список параметров>): <тип>; <директивы>; Здесь <> используются для обозначения содержания Структура тела процедуры или функции аналогична телу программы, т. е. как и программа может содержать все разделы
Механизм параметров Через параметры процедуры и функции получают и выдают данные. При объявлении процедур и функций описание параметров определяет возможности процедур и функций по дальнейшей работе с получаемыми и выдаваемыми ими данными, поэтому на стадии объявления параметры называются формальными. На стадии выполнения процедур и функций на место формальных параметров подставляются конкретные данные, которые называются фактическими параметрами. Основное требование: При описании и выполнении процедур и функций 1)количество, 2)порядок следования и 3)типы формальных и фактических параметров должны полностью совпадать. Данные, поступающие в процедуру или функцию через параметры в соответствующих разделах процедуры или функции описывать не нужно.
Виды параметров и их использование (1) Одновременно в процедуре и функции могут использоваться любые виды параметров. Параметры-значение procedure First(P 1: integer; P 2: real); используются только как входные, их значения не изменяются, в качестве таких параметров могут использоваться константы и выражения. При работе процедуры или функции эти параметры копируются и, значит занимают двойную память.
Виды параметров и их использование (2) Параметры-переменные procedure Second(var Q 1: integer; var Q 2: real); могут использоваться как входные, так и выходные, в качестве таких параметров нельзя использовать константы и выражения. При работе процедуры или функции эти параметры не копируются, их значения могут изменяться, а значит существует вероятность ошибочного вывода значений, приводящих к побочным эффектам.
Виды параметров и их использование (3) Параметры-константы procedure Third(const R 1: integer; const R 2: real); используются только как входные, их значения не изменяются, в качестве таких параметров нельзя использоваться константы и выражения. При работе процедуры или функции эти параметры не копируются (так как в процедуру передается не сам параметр, а только адрес параметра без возможности записи по этому адресу).
Виды параметров и их использование (4) Существуют еще Нетипизированные параметры (для формальных параметров не указан тип); Параметры-процедуры (в качестве параметров могут выступать процедуры и функции); Параметры - открытые регулярные данные (в качестве параметров могут выступать открытые массивы и строки, т. е. массивы и строки без указания количества элементов в них) Эти типы параметров будут рассмотрены позже
Использование процедур и функций (1) Перед созданием программы необходимо выделить достаточно обособленные (локально независимые) блоки действий, которые необходимо оформить в виде процедур и функций. Процедуры и функции могут быть использованы в любом месте тела программы, включая циклы и блоки операторов begin-end. Вызов процедуры и функции осуществляется по их именам с указанием фактических параметров (если они имеются). При этом фактические параметры должны быть заранее объявлены в основной (по отношению к процедуре или функции) программе и получить конкретные значения. Перед выходом из функции результирующее значение, полученное в результате работы функции должно быть присвоено имени функции или системной функции Result (без указания параметров) в теле самой функции. Перед выходом из процедуры результирующие значения, полученные в результате работы процедуры должны быть присвоены соответствующему параметру-переменной в теле самой процедуры.
Использование процедур и функций (2) Выход (прерывание действия) из процедуры и функции может быть осуществлен по команде (стандартной процедуре) exit, которую можно ставить в любом месте тела процедуры или функции. В противном случае процедура или функция выполнится полностью и вернет управление программе в точку, следующую за ее вызовом. По goto выходить из процедуры и функции нельзя.
Области действия имен (1) Так как структура процедуры и функции (подпрограммы) подобна структуре самой программы, то в них также можно объявлять любые объекты (метки, константы, типы, переменные, а также процедуры и функции), но тогда какова область их действия? Правила определения областей действия имен объектов u Имена, определенные в некоторой подпрограмме, считаются известными в пределах данной подпрограммы, включая и все вложенные в нее подпрограммы. u Имена объектов, описанных в подпрограмме, должны быть уникальны в пределах данной подпрограммы, но могут совпадать с именами из других подпрограмм (хотя это и нежелательно)
Области действия имен (2) Если в некоторой подпрограмме описан объект, имя которого совпадает с именем объекта, описанного в объемлющей подпрограмме, то действует правило последнего объявления, т. е. имя, описанное во внешней (объемлющей) подпрограмме будет закрыто для использования его во внутренней подпрограмме. Если же все имена различны, то подпрограмма будет видеть (иметь возможность использовать) и свои имена и все внешние по отношению к ней имена. Наоборот – невозможно, т. е. сама программа не видит имен своих подпрограмм.
Области действия имен (3) Совокупность имен, описанных в самой подпрограмме, по отношению к этой подпрограмме называется локальным контекстом. Совокупность имен, описанных вне подпрограммы, по отношению к этой подпрограмме называется глобальным контекстом. В соответствии с правилами подпрограмме всегда доступен глобальный контекст, поэтому его всегда можно передать подпрограмме не через параметры, а напрямую (что некоторые программисты-любители и делают), но это плохой стиль программирования и лучше этого не делать.
Директивы (1) Директивы дают дополнительную информацию компилятору по размещению подпрограммы, организации связи между подпрограммами, порядке передачи параметров и др. Директива может располагаться сразу за заголовком процедуры или функции, в виде некоторого зарезервированного слова (например, forward, far или другое) в этом случае она действует на всю процедуру или функцию. Например, procedure Direct(P 1: integer; var Q 1: real); forward;
Директивы (2) Директива может иметь и специальный вид (вид комментария). Например, {$F+}. В этом случае директива может размещаться в любом месте подпрограммы или программы и действует с места размещения до места ее отмены, например, {$F-}. ……. . <операторы> {$F+} ……. . <операторы> {$F-} ……. . <операторы>
Ближняя и дальняя модель вызова подпрограмм Пояснение ближней модели вызова (действует по умолчанию) Пояснение дальней модели вызова Директивы near, far Директивы {$F-}, {$F+}
Рекурсия (1) Рекурсия — это такой способ организации вспомогательного алгоритма (подпрограммы), при котором эта подпрограмма (процедура или функция) в ходе выполнения ее операторов обращается сама к себе. Происходит от лат. recursio «круговорот, возврат» , родств. recurrere «бежать назад, возвращаться, опять приходить» ; Вообще, рекурсивным называется любой объект, который частично определяется через себя. «Итерация свойственна человеку, рекурсия – Богу (божественна)» . - Л. Питер Дойч
Рекурсия (1 -1) Рекурсия в физике Классическим примером бесконечной рекурсии являются два поставленные друг напротив друга зеркала: в них образуются два коридора из затухающих отражений зеркал. Рекурсия в литературе 1. «У попа была собака…» 2. Д. Хармс «Дом, который построил Джек…» и др. 3. «Чтобы понять рекурсию, нужно сначала понять рекурсию»
Рекурсия (2) Обращение к рекурсивной подпрограмме ничем не отличается от вызова любой другой подпрограммы. При этом при каждом новом рекурсивном обращении в памяти создаётся новая копия подпрограммы со всеми локальными переменными. Такие копии будут порождаться до выхода на граничное условие, которое обычно отражается в качестве параметра. Очевидно, в случае отсутствия граничного условия возникает бесконечная рекурсия и неограниченный рост числа таких копий приведёт к аварийному завершению программы за счёт переполнения памяти, отведенной для размещения рекурсивных вызовов подпрограмы (стека рекурсии).
Рекурсия (3) Порождение все новых копий рекурсивной подпрограммы до выхода на граничное условие называется рекурсивным спуском. Максимальное количество копий вызовов рекурсивной подпрограммы, которое одновренно может находиться в памяти компьютера (стеке рекурсии), называется глубиной рекурсии. Завершение работы рекурсивных подпрограмм, вплоть до самой первой, инициировавшей рекурсивные вызовы, называется рекурсивным подъёмом.
Рекурсия (4) Выполнение действий в рекурсивной подпрограмме может быть организовано одним из вариантов: алг Р алг Р нач P операторы P P кон операторы кон (рекурсивный (и рекурсивный спуск, подъем) спуск) и рекурсивный подъем)
Рекурсия (5) Пример 5. 1. Классический пример, без которого не обходится ни одно представление рекурсии, — определение факториала – fact(n). С одной стороны, факториал определяется так: fact(n)=n!=1*2*3*. . . *n. С другой стороны, его можно определить рекурсивно fact(n)=fact(n-1)*n Граничным условием в данном случае является n<=1.
Рекурсия (6) Function Factorial(N: integer): Extended; begin If N<=1 Then Factorial: =1 Else Factorial: = Factorial(N-1)*N end; Рис. 5. 1 Схема выполнения рекурсии
Рекурсия (7) Пример 5. 2. Определим Procedure K(N: Longint; Var процедуру K(n), которая Kol: Byte); возвращает количество Begin цифр в заданном If N<10 Then Kol: =1 натуральном числе n: Else Begin K(N Div 10, Kol); Kol: =Kol+1 End;
Рекурсия и итерация Что проще и в каких случаях? Вычисление факториала итеративно Вычисление факториала рекурсивно
Можно ли обойтись без рекурсии? Да! Все универсальные языки программирования (включая Паскаль) позволяют для всякой рекурсивной программы написать эквивалентную программу без рекурсии. Тем более, что 1) с позиций эффективности исполнения программы во многих компьютерах (в том числе, к сожалению, и в современных, использующих так называемые RISC-процессоры), рекурсивные программы в несколько раз медленнее соответствующих нерекурсивных программ; 2) в некоторых языках программирования рекурсивные программы просто запрещены Отсюда, Рекурсией большей частью пользуются для простоты и прозрачности представления алгоритма
Где используется рекурсия В программировании Рекуррентных формул (от лат. recurrere «бежать назад, возвращаться, опять приходить» ): числа Фибоначчи, комбинаторные формулы (число сочетаний и др. ), полиномы Чебышева, полином Лежандра, функции Бесселя 2 -го рода, многочлен Эрмита, многочлен Лаггера, числа Бернулли, вычисление интегралов, сложных сумм, произведений и др. Логических задач при повторяющихся действиях, но с различными параметрами Обходы деревьев (графов) и др.
Числа Фибоначчи (1) Числа Фибоначчи задаются рекуррентной формулой: F(n)=1, при n=1 и n=2 F(n)=F(n-1)+F(n-2), при n>2 И, значит, могут быть вычислены рекурсивно. Задание. Написать рекурсивную процедуру вычисления чисел Фибоначчи
Числа Фибоначчи (2) Или по формуле, используя выражение для «золотого сечения» (первый числитель)
Числа Фибоначчи (3). А можно и через континуанту Континуантой индекса n называется многочлен , определяемый рекуррентным соотношением Континуанта может быть выражена через определитель от 3 -х диагональной матрицы Отсюда F(n)=Kn (x 1, x 2, … , xn) при x =1
Некоторые рекуррентные формулы (1) Значение интеграла удовлетворяет рекуррентной формуле: Другие рекуррентные формулы для вычисления интегралов см. http: //www. pm 298. ru/rtab_integral. php
Некоторые рекуррентные формулы (2) Любые ортогональные полиномы (т. е. полиномы скалярное произведение которых равно 0) удовлетворяют рекуррентной формуле см. http: //ru. wikipedia. org/wiki/%D 0%9 E%D 1%80 %D 1%82%D 0%BE%D 0%B 3%D 0%BE%D 0 %BD%D 0%B 0%D 0%BB%D 1%8 C%D 0%B D%D 1%8 B%D 0%B 5_%D 0%BC%D 0%BD% D 0%BE%D 0%B 3%D 0%BE%D 1%87%D 0% BB%D 0%B 5%D 0%BD%D 1%8 B
Функция Аккермана (1) В теории вычислимых функций существует понятие примитивно рекурсивных функций, т. е. функций построенных из базисных с помощью некоторой последовательности операций подстановки и рекурсии. Главный вопрос: существуют ли общерекурсивные, но не примитивно рекурсивные функции? Немецкий математик Вильгельм Фридрих Аккерман (1896 -1962) построил рекурсивную функцию A(n, m) - функция Аккермана, которая растет быстрее любой примитивно рекурсивной функции, и, значит, не сводится к ним.
Функция Аккермана (2) A(m, n) определяется для всех неотрицательных целых аргументов m и n следующим образом:
Функция Аккермана (3) Текст функции на Object Pascal function akker(m, n: extended): extended; begin if m=0 then akker: =n+1; if (m>0) and (n=0) then akker: =akker(m-1, 1); if (m>0) and (n>0) then akker: =akker(m-1, akker(m, n-1)); end;
Функция Аккермана (4) Функция Аккермана растёт очень быстро, например, число A(4, 4) настолько велико, что количество цифр в порядке этого числа многократно превосходит количество атомов в наблюдаемой части Вселенной (см. Таблицу)
Функция Аккермана (5) nm 0 1 2 3 4 0 1 2 3 5 13 65533 2 3 4 7 29 265536 − 3 3 4 5 9 61 4 5 6 11 125 5 6 7 13 253 2 n + 3 − 3 n n + 1 n + 2
Рекурсивная сортировка слиянием (1) Процедура Sort(A, B, b 1, e 2) сортировки слиянием. Алгоритм должен копировать со слиянием два упорядоченные куска из массива А с номерами от b 1 до e 1 и от e 1+1 до e 2 соответственно в массив В с номерами элементов от b 1 до e 2. Алгоритм сортировки : если длина сортируемого массива 1, то ничего не делается; в противном случае массив делится на две одинаковые (или почти одинаковые) части, к каждой части применяется алгоритм сортировки, после чего эти упорядоченные части сливаются в один упорядоченный кусок.
Рекурсивная сортировка слиянием (2) Рассмотрим процедуру сортировки слиянием. На вход процедуры сортировки поступает неупорядоченный кусок массива А с номерами элементов от b до e, на выходе - тот же кусок, но упорядоченный. Массив С - вспомогательный. Procedure Sort 2(Var A, C : Array 1; b, e : integer); Var i, d : integer; Begin if b<e then begin d : = (b+e) div 2; Sort 2(A, C, b, d); Sort 2(A, C, d+1, e); Sort(A, C, b, d, e); for i : = b to e do A[i] : = C[i] end; End;
Ханойская башня (1) Легенда. Во вьетнамском монастыре Бенареса находится бронзовая плита с 3 -мя алмазными стержнями на один из которых Бог при сотворении мира нанизал 64 золотых диска разных диаметров в виде пирамиды. Это башня Брамы. Работая день и ночь монахи переносят диски с одной иглы на другую следуя законам Брамы: 1) диски можно перемещать с одного стержня на другой только по одному; 2) нельзя класть больший диск на меньший; 3) при переносе дисков с одного стержня на другой можно использовать промежуточный третий стержень, на котором диски должны находиться тоже только в виде пирамиды. Как только они решат эту задачу наступит конец света. Итак, когда же наступит конец света?
Ханойская башня (2) Трехмерный вариант Ханойской башни
Ханойская башня (3) Hапишем рекурсивную процедуру перемещения M верхних колец с A-го стержня на B-ый в предположении, что остальные кольца больше по размеру и лежат на стержнях без движения:
Ханойская башня (4) Рекурсивная идея Сначала переносится пирамидка из M-1 колец на третий стержень C. После этого M-ое кольцо (большего диаметра) освобождается, и его можно перенести на B. Остается перенести пирамиду из M-1 кольца с C на B. Чем это проще первоначальной задачи? Тем, что количество колец стало на единицу меньше.
Ханойская башня (5) Схема перемещения дисков Рис. 5. 2
Ханойская башня (6) procedure Move(M, A, B: integer); var C: integer; begin if M=1 then begin writeln ('сделать ход ', A, '->', B) end else begin C: =6 -A-B; {C - третий стержень: сумма номеров равна 6} Move(M-1, A, C); Move(1, A, B); Move(M-1, C, B) end;
Ханойская башня (7) Теперь основную программу можно записать в несколько строк: program Hanoi; var N: integer; procedure Move(M, A, B: integer); . . . begin write('N='); readln(N); Move(N, 1, 2) end.
Ханойская башня (8) Подсчет числа ходов Оценим, сколько переносов будет сделано и сколько шагов выведено при работе программы. Обозначим Тn - число ходов, необходимых для переноса n колец. Очевидно, что Тo = 0, T 1=1, Т 2=3, Т 3=7, Т 4=15, и т. д. Т. е. Т(n) = 2^n-1 или Т(n) = 2 x Т(n-1) + 1 при n>0, отсюда получаем: Т(64) = 2^64 - 1 = 2 x 10^19 Если считать, что на перенос одного кольца потребуется одна секунда, то на перенос всех колец потребуется более 5 млрд веков.
Резюме по рекурсии (1) Таким образом, ОСHОВHАЯ ИДЕЯ любого рекурсивного решения - свести задачу к точно такой же, но с меньшим значением параметра. При этом какое-то минимальное значение параметра (например, 1 или 0) должно давать решение без рекурсивного вызова - иначе программа "зациклится" (последовательность рекурсивных вызовов будет бесконечной). Это напоминает метод математической индукции в математике. В некоторых задачах удобно наоборот, увеличивать значение параметра при рекурсивном вызове. Тогда, естественно, "безрекурсивное" решение должно предусматриваться для некоторого максимального значения параметра. Эти идеи можно использовать для перебора комбинаторных объектов.
Резюме по рекурсии (2) Мощь рекурсивного определения и его главное значение состоит в том, что с помощью конечного выражения можно определить бесконечное множество объектов (или вычислений). Для создания рекурсивного алгоритма необходимо и достаточно наличия процедуры или функции.
Упражнения 1. Напишите рекурсивную процедуру, которая для двух заданных натуральных чисел определяет их наибольший общий делитель. 2. Напишите рекурсивную процедуру поиска корня уравнения вида f(x) = 0 на промежутке [а, b] методом деления отрезка пополам. 3. Напишите рекурсивную функцию summ(s, i, j), проверяющую, является ли симметричной часть строки s, начинающаяся i-м и заканчивающаяся i-м ее элементами. 4. Напишите рекурсивную функцию, "переворачивающую" заданное натуральное число. 5. Напишите рекурсивную функцию, которая по последовательности литер, представляющих двоичное исло, определяет соответствующее десятичное число. 6. Напишите рекурсивную функцию, вычисляющую n!!. 7. Напишите рекурсивную функцию, определяющую количество единиц в двоичном представлении натурального числа. 8. Напишите рекурсивную функцию, которая по заданным натуральным числам m и п выводит все различные представления числа « в виде суммы m натуральных слагаемых. Представления, различающиеся лишь порядком слагаемых, считаются одинаковыми. 9. Напишите рекурсивную функцию, которая формирует в обратном порядке текст, задаваемый пользователем в текстовом поле формы. 10. Напишите рекурсивную функцию для вычисления биномиального коэффициента C. 11. Напишите рекурсивную функцию, проверяющую, является ли последовательность символов идентификатором. Напомним, что идентификатором будем считать последовательность букв и/или цифр, начинающуюся с буквы. 12. В последовательности символов могут встречаться только цифры и знаки + (плюс), при этом последовательность представляет собой формулу сложения однозначных чисел. Напишите рекурсивную функцию, определяющую значение формулы. 13. В последовательности символов могут встречаться только цифры и знаки + (плюс) или - (минус), при этом последовательность представляет собой формулу арифметической суммы однозначных чисел. Напишите рекурсивную функцию, определяющую значение формулы.
Косвенная рекурсия (1) Когда подпрограмма вызывает сама себя непосредственно, то мы имеем дело с явной рекурсией. Явный вызов: Но подпрограмма может вызывать саму себя и косвенно через другие подпрограммы. Косвенный вызов Например, А вызывает В, а В вызывает А. В этом случае обе подпрограммы рекурсивны
Косвенная рекурсия (2) procedure A(…); begin ……. . B(…); ……. . end; Procedure B(…); begin ……. . A(…); ……. . end;
Реализация косвенной рекурсии. Опережающее описание Procedure B(…); forward; {директива forward предполагает дальнюю модель вызова } procedure A(…); begin ……. . B(…); ……. . end; Procedure B; begin ……. . A(…); ……. . end;
Тезаурус по рекурсии http: //www. mgopu. ru/PVU/2. 1/Recurs/OOD/Termin/trm_inf. htm#24 Адаптивный рекурсивный алгоритм Отложенные вычисления Рекурсивная траектория Визуальное мышление Параметризация задачи Рекурсивная триада Возвратная рекурсия Повторительная рекурсия Рекурсивное мышление Воплощение Полная рекурсивная траектория Рекурсивные вычисления Вспомогательные параметры рекурсии Полное дерево рекурсивных вызовов Рекурсивные обращения Глубина рекурсивных вызовов Предвычисления (предварительные вычисления) Рекурсивные определения Декомпозиция Производящая функция Рекурсивный алгоритм (процедура, функция) Дерево рекурсивных вызовов Пространство параметров Рекурсивный стек (магазин, штабель) Динамическая рекурсивная база Прямая рекурсия Рекурсия Индикаторы завершения рекурсивных вызовов Прямой и обратный ход вычислений Рекурсограмма Каскадная (древовидная) рекурсия Рабочая ветвь рекурсивного алгоритма Срез рекурсивных вычислений Корень полного дерева рекурсивных вызовов Рекуррентное соотношение (рекуррентная формула) Терминальная ветвь рекурсивного алгоритма Косвенная (взаимная) рекурсия Рекурсивная база Удаленная рекурсия Линейная рекурсия Рекурсивная машина обработки формуляров Управляющие параметры рекурсии Объем рекурсии Рекурсивная тавтология Формуляр
Тест Джимми Прота на способность к решению самоссылающихся задач Сам тест см. , например, на http: //forum. megatula. ru/viewtopic. php? t=1389 Протестироваться можно на http: //www. mozg. ru/visitor/login? do. next=/g 3/ses sion/start/392
Л-4 Орг подпр. Рекурсия.ppt