- •Тема "Рекурсия". Глава 1. Рекурсия. Основные положения.
- •1.1. Рекурсивные алгоритмы.
- •1.2. Рекурсивные процедуры и функции. Взаиморекурсия.
- •1.3. Фрейм активации.
- •Var a,b,r:integer;
- •Var a,b,r:integer;
- •Var a,b,eps,X:real;
- •Var f,X:real;
- •Var s:string;
- •If f_char(s) then writeln(' Строка корректна')
- •Var s:string;
- •If f_char(s,1) then writeln('Строка корректна')
- •I:integer;
- •Глава 2. Полный и ограниченный перебор. Рекурсия при программировании ограниченного перебора.
- •2.1. Понятие полного перебора. Основные приемы его осуществления.
- •Var I:integer;
- •Var pole:p; I,m:integer;
- •Var I,j:integer;
- •Var I:integer;
- •If New_r(m,pole) then
- •2.2. Использование рекурсии при реализации ограниченного перебора.
- •Var pole:p; k,integer;
- •Var j:integer;
- •Var I:integer;
Var I:integer;
begin
while a[1]<4 do {условие "сброса" счетчика}
begin for i:=1 to 4 do write(a[i],' '); writeln; {вывод комбинации}
a[4]:=a[4]+1; {добавление 1 в последний разряд}
for i:=4 downto 2 do { анализ и осуществление переносов}
if a[i]>3 then
begin a[i]:=1; a[i-1]:=a[i-1]+1; end;
end
end.
Этот прием можно использовать и для решения других задач данного класса.
Пример 3.Задача о расстановке ферзей.
Разработка программы решения начинается с выявления некоторых деталей.
Рис.8.
Определим, что для векторного представления означает "бьет". Ферзь "бьет" другую фигуру, если она расположена на той же диагонали, вертикали или горизонтали, т.е. если
pole[ j ]=pole[ i ] или| pole[ j ]-pole[ i ] | =| j- i |
Полностью решение выглядит следующим образом:
program ex;
type p=array[1..100] of integer;
Var pole:p; I,m:integer;
function new_r(m:integer;pole:p):boolean; {функция проверки комбинации}
Var I,j:integer;
begin new_r:=true;
for i:=1 to m-1 do
for j:=i+1 to m do
if (pole[i]=pole[j]) or (abs(pole[j]-pole[i])=j-i) then
begin new_r:=false;
exit;
end;
end;
function Variant(m:integer; var pole:p):boolean; {генератор вариантов}
Var I:integer;
begin
pole[m]:=pole[m]+1; {добавление единицы в младший разряд счетчика}
for i:=m downto 2 do {обработка переносов}
if pole[i]>m then
begin pole[i]:=1;
pole[i-1]:=pole[i-1]+1;
end;
if pole[1]<=m then Variant:=true {фиксируем наличие ранее не рассмотренных}
else Variant:=false; {вариантов}
end;
begin writeln('Введите размер доски'); readln(m);
for i:=1 to m do pole[i]:=1; {исходная комбинация}
repeat
If New_r(m,pole) then
begin for i:=1 to m do write(pole[i]:2); writeln; end;
until not Variant(m,pole);
end.
Недостаток примененного метода, как уже говорилось, заключается в mm-ой зависимости времени выполнения от значенияm.
2.2. Использование рекурсии при реализации ограниченного перебора.
Попробуем сократить количество рассматриваемых вариантов за счет как можно более раннего отбрасывания неперспективных комбинаций. На рис.9 представлена часть дерева промежуточных и завершенных вариантов.
Рис. 9.
Рис. 10.
program ex;
type p=array[1..100] of integer;