Вход

ПРЗ на ЭВМ ( метод рекурсии)

Реферат по программированию
Дата добавления: 26 июня 2005
Язык реферата: Русский
Word, rtf, 314 кб (архив zip, 33 кб)
Реферат можно скачать бесплатно
Скачать
Не подходит данная работа?
Вы можете заказать написание любой учебной работы на любую тему.
Заказать новую работу





Рекурсия

Рекурсия – это метод программирования, при котором процедура или функция непосредственно или через другие процедуры (или функции) обращается сама к себе как ко вложенной процедуре (или функции). Это бывает необходимо или удобно для решения целого ряда задач. При использовании рекурсии текст программы и ее алгоритм сокращается и упрощается в несколько раз. Рекурсию следует использовать с осторожностью, так как иногда слишком много рекурсивных вызовов быстро исчерпывают свободную память.

Примеры решения задачи с использованием рекурсии:


Задача 1

Имеется n населенных пунктов, перенумерованных от 1 до n (n=10). Некоторые пары пунктов соединены дорогами. Определить с применением рекурсии, можно ли попасть по этим дорогам из 1-го пункта в n-й. Информация о дорогах задается в виде пар чисел i и j (i


uses crt;

const

nn=10;

var

rout,r:string;

a:array[0..nn,0..nn] of char;

i,j,n:integer;

c:char;

ok:boolean;

procedure router(otkuda,gde ,kuda:integer;var ok:boolean); {рекурсивная про-}

var i:integer; {цедура }

begin

a[gde,otkuda]:='?'; { ставится на время выполнения процедуры для }

a[otkuda,gde]:='?'; {исключения зацикливания процедуры}

if gde=kuda then begin str(kuda,r); ok:=true end

else

for i:=1 to nn do { цикл проверки пути по всем направлениям}

begin

if (ok=false)and(a[i,gde]='y')

then begin router(gde,i,kuda,ok);{ рекурсивный вызов процедуры}

if ok=true then

begin str(gde,r); end

end

end;

a[gde,otkuda]:='y'; { y - в данном направлении есть дорога}

a[otkuda,gde]:='y';

end;

begin {начало программы}

clrscr;

writeln('Введите пути ');

repeat

write('Откуда '); readln(i);

if i<>0 then begin

write(Куда  '); readln(j); writeln(i,' =>',j);

if j<>0 then

if (i>nn)or(j>nn) then writeln(‘Неверный ввод ')

else

begin a[i,j]:='y';a[j,i]:='y'end else;

end

until (i=0)or(j=0);


repeat

ok:=true;

repeat

write('Куда попасть из №1 ? ');

rout:='';

readln(n);

if n<=0 then writeln('Нет такого! ')

else if n=1 then writeln('Уже здесь! ')

else ok:=false;

until ok=false;

router(0,1,n,ok); {результат: ok=false – дороги нет, ok=true – дорога есть }

if ok=false then writeln('Нельзя ')

else writeln('Можно ');


c:=readkey;

until c=' ';

end.


Введите пути

Откуда 1

Куда 2

1 =>2

Откуда 1

Куда 4

1 =>4

Откуда 2

Куда 3

2 =>3

Откуда 4

Куда 6

4 =>6

Откуда 4

Куда 5

4 =>5

Откуда 6

Куда 10

6 =>10

Откуда 00

Куда попасть из #1 ? 10

Можно







Задача 2

Описать рекурсивную функцию pow(x,n) от вещественного x (x

0) и целого n, которая вычисляет величину согласно формуле:

1 , при n=0;

= 1/ , при n<0>

x , при n>0

uses crt;

var n:integer;

x:real;

function pow(x:real; n:integer): real; {рекурсивная функция}

begin

if n=0 then pow:=1 else

if n<0>

pow:=x*pow(x,n-1); {рекурсивный вызов pow}

end;

begin {начало программы}

clrscr;

write('Введите x: ');read(x);

write('Введите n: ');read(n);

writeln('pow = ',pow(x,n):2:3);

readkey;

end.



x: 2

n: 0

pow = 1.000


x: 2

n: 3

pow = 8.000


x: 2

n: -3

pow = 0.125




Перечислимые типы

Перечислимый тип – это тип составленный из множества упорядоченных элементов. Перечислимый тип задается перечислением всех своих элементов, то есть перечисляются все возможные значения переменных этого типа. Над переменными перечислимого типа можно выполнять только операции отношения, поскольку значения перечислимого типа упорядочены, то есть каждому значению ставится в соответствие его порядковый номер.


Задача

Type страна =(Германия, Куба, Лаос, Монако, Непал, Польша); континент =(Азия, Америка, Европа). По s – названию страны определить c – название континента.


uses crt;

type kontinent=(Azia,Amerika,Evropa); {перечислимые типы}

strana=(Germania,Kyba,Laos,Monako,Nepal,Polsha);

var c:kontinent;

s:strana; x:string;

begin {начало программы}

clrscr;

write(‘Введите название страны: ',x);readln(x);

if x='Германия' then s:=Germania;

if x='Куба ' then s:=Kyba;

if x='Лаос' then s:=Laos;

if x='Монако' then s:=Monako;

if x='Непал' then s:=Nepal;

if x='Польша' then s:=Polsha;

case s of {выбор континента по стране}

Laos,Nepal: c:=Azia;

Kyba: c:=Amerika;

Germania,Monako,Polsha: c:=Evropa;

end;

if c=Azia then writeln('Континент: Азия'); {вывод на экран}

if c=Amerika then writeln('Континент: Америка ');

if c=Evropa then writeln('Континент: Европа ');

readln;

end.



введите название страны: Куба

Континент: Америка


введите название страны: Германия

Континент: Европа


введите название страны: Лаос

Континент: Азия






Динамические переменные

Динамические переменные – это переменные, которые могут создаваться и уничтожаться в процессе работы программы. Динамические переменные применяются тогда, когда заранее не известно какой объем переменных потребуется в программе, либо для организации таких структур данных как списки или деревья.



Задача

(* Работа с динамическими переменными - организация списков *)

USES CRT;

Type Str = string[80];

Adr = ^Zap;

Zap = Record

Inf : Integer;

Ssylka : Adr

End;

procedure sort(Var Nach:adr);

(* =============Сортировка списка ===============*)

Var i,n:integer;Q:Boolean; P,X:Adr;

Begin n:=0; Q:=false;

If Nach=Nil then writeln('Список отсутствует, введите список ')

else Begin P:=Nach; while P<>Nil do Begin n:=n+1; P:=P^.Ssylka end;

while not Q do begin Q:=true;P:=Nach;

if Nach^.inf > Nach^.Ssylka^.inf

then begin Nach:=Nach^.Ssylka;

P^.Ssylka:=Nach^.Ssylka; Nach^.Ssylka:=P; Q:=false;

end;

x:=Nach^.Ssylka;P:=Nach;

for i:=1 to (n-2) do

if x^.inf > x^.Ssylka^.inf then begin

p^.Ssylka:= x^.Ssylka; x^.Ssylka:=x^.Ssylka^.Ssylka;

P^.Ssylka^.Ssylka:=x; P:=P^.Ssylka; Q:=false

end

else begin P:=x;x:=x^.Ssylka end;

end;

end;

end;

Procedure Print (P:Adr);

(* ====================Вывод списка на экран ­=============== *)

Var R:Adr;

Begin Writeln;

Writeln('______________Печать списка _________');

R:=P; Writeln;

While R<>Nil Do

Begin Write(R^.Inf,' ');

R:=R^.Ssylka

End;

Writeln;Writeln;Writeln('Список окончен')

End;

Procedure sch(Nach:adr);

(* ====================Подсчет числа элементов списка ========*)

var r:adr;

i:integer;

begin i:=0; r:=nach;

while r<>nil do

begin i:=i+1;

r:=r^.ssylka

end;

writeln('Количество элементов’,i);

end;

procedure DobKon(Var Nach:Adr);

(* ====== Создание списка путем добавления элементов в конец ====== *)

Var R,Q:Adr;A:integer;

Begin Nach:=Nil;

Repeat write('Введите число, признак конца  999 ');readln(A);

if A <> 999 then Begin

if Nach=Nil

then Begin New(Nach);Nach^.inf:=A;Nach^.Ssylka:=Nil;Q:=Nach;end

else Begin New(Q^.Ssylka);Q:=Q^.Ssylka;Q^.inf:=A;Q^.Ssylka:=NIL;

end

end

Until A=999;

end;

procedure DobNach(Var Nach:Adr);

(* ====== Создание списка путем добавления элементов в начало ==== *)

Var R : Adr;

A : Integer;

begin nach:=nil;

repeat write ('Введите число, признак конца  999 ');

readln(a);

if a<>999 then begin

new(r);

r^.inf:=a;

r^.ssylka:=nach;

nach:=R;end

Until a=999

end;

var R: integer;

Function Poisk(Nach:Adr;R:Integer):Adr;

(* ===== Поиск элемента R в списке (рекурсивный)===================*)

(* результат -  адрес этого элемента Nil, если элемент не найден *)

Begin If Nach=Nil Then Poisk:=Nil

Else If Nach^.Inf=R Then Poisk:=Nach

Else Poisk:=Poisk(Nach^.Ssylka,R);


end;

Procedure VstavZ(Nach:Adr);

(*===Вставка в список элемента после элемента с заданным значением ===*)

Var AZ,AVst,R:Adr;{Адрес заданного элемента и адрес вставленного, рабочий адрес}

Z :Integer;

Begin Write('Введите элемент, после которого хотите произвести вставку ');

Readln(Z);

R:=Nach;

While (R^.Ssylka<>Nil) And (R^.Inf<>Z) do

{пока не закончится список или не найдется нужный элемент}

R:=R^.Ssylka; {продвигаемся по списку}

If R^.Inf<>Z Then Writeln('Заданного элемента нет')

Else Begin New(Avst);

Avst^.Ssylka:=R^.Ssylka;

Write('Что хотите вставить? ');

Readln(Avst^.Inf);

R^.Ssylka:=Avst

End

End;

Procedure IsklN(Var Nach:Adr);

(*=======Исключение из списка элемента с заданным номером =======*)

Var N, I : Integer; {Номер исключаемого элемента, текущий номер}

R : Adr; {Текущий адрес}

Begin Write('Введите номер удаляемого элемента '); Readln(N);

If N=1 Then Nach:=Nach^.Ssylka

Else Begin R:=Nach; I:=1;

While (R^.SSylka<>Nil) And (I

Begin R:=R^.Ssylka; I:=I+1 End;

If R^.ssylka=Nil Then Writeln('Элемента с таким номером нет’)

Else R^.Ssylka:=R^.Ssylka^.Ssylka

End

End;

Procedure PrintF(Var Nach:Adr;Var S:str);

(* ===== Запись списка в файл на диск ======= *)

Var F:Text;R:Adr;

Begin Write('Имя файла? ');readln(s);

Assign(F,s); rewrite(F);

If Nach<>nil then Begin writeln(F,'---- Список элементов ----');

writeln(F); R:=Nach;

While r<>Nil do

Begin write(F,R^.inf:6);

R:=R^.Ssylka

end; writeln(F);writeln(f);

Writeln(F,'----- Список окончен -----'); close(F);

Writeln('Запись списка в файл ',s,' произведена');

end

else writeln('Список отсутствует, введите список');

end;

function Kolich(Var Nach:Adr;r:integer):integer;

(* ===== Сколько раз встречается заданный элемент ======= *)

var P:adr;

i:integer;

begin i:=0; P:=nach;

while P<>nil do

begin

if P^.inf=r then i:=i+1;

P:=P^.ssylka

end;

Kolich:=i;

END;

procedure Skleika(var Nach:adr;var Nach1:adr);

var r:adr;

begin

r:=nach;

while r^.ssylka<>nil do r:=r^.ssylka;

r^.ssylka:=nach1;

end;

{-------------------------------------------------------------------}

Var F : Text;

x,y,t,Xx : Integer;

s,key : Char;

s1 : Str;

Var Nach,Nach1,q,PPP : Adr;

Const K=12;{Количество вариантов в "меню"}

Begin

Nach:=Nil;

Repeat

x:=3; y:=1;

ClrScr;

Writeln (' 0. Конец работы');

Writeln (' 1. Печать списка  ');

Writeln (' 2. Создание списка путем добавления элементов в начало');

Writeln (' 3. Есть ли в списке заданный элемент');

Writeln (' 4. Вставка элемента после заданного');

Writeln (' 5. Удаление элемента с заданным номером');

Writeln (' 6. Сколько раз встречается заданный элемент’);

Writeln (' 7. Подсчитать количество элементов списка’);

Writeln (' 8. Склеить два списка');

Writeln (' 9. Создание списка путем добавления элемента в конец ');

Writeln (' 10. Запись списка в файл на диск ');

Writeln (' 11. Сортировка списка');

Repeat Gotoxy(X,Y);

s:=readkey; if s=#0 then s:=readkey;

t:=ord(s);

Case t of

72:if y>1 then y:=y-1 else y:=k;

80:if y

End;

Until t=13;

ClrScr;

Case Y-1 of

1:Begin writeln('Использовать Print(Nach)');

Print(Nach);

end;

2: Begin writeln('Использовать DobNach(Nach);Print(Nach)');

DobNach(Nach);

Print(Nach);

end;

3: Begin writeln(' Использовать Print(Nach),Poisk(Nach,R)');

repeat;

Print(Nach);

write('Введите элемент, который надо найти :');

readln(R);

ppp:=Poisk(Nach,R);

if ppp<>nil then writeln('Элемент найден ',ppp^.inf)

else writeln('Элемент не найден');

Print(Nach);

writeln;writeln('Повторить?');

until readkey='n';

end;

4: Begin writeln(' Использовать Print(Nach),VstavZ(Nach)');

repeat

Print(Nach);

VstavZ(Nach);

Print(Nach);

writeln;writeln('Повторить?');

until readkey='n';

end;

5: Begin writeln(' Использовать Print(Nach),IsklN(Nach)');

repeat

Print(Nach);

IsklN(Nach);

Print(Nach);

writeln;writeln('Повторить?');

until readkey='n';

end;

6: Begin writeln('Создать свою процедуру Kolich(Nach)');

Print(Nach);

write('Введите элемент, который надо найти: ');

readln(R);

writeln('Элемент в списке встречается ',Kolich(Nach,r),' раз(а)');

end;

7: Begin writeln('Использовать print(Nach) и sch(Nach)');

print(Nach);

sch(Nach);

end;

8: Begin writeln('Создать свою процедуру Skleika(Nach,Nach1)');

writeln('Введите второй список ');

dobkon(nach1);

print(nach);

print(nach1);

Skleika(Nach,Nach1);

print(nach);

end;

9: Begin

writeln('Использовать DobKon(Nach);Print(Nach)');

DobKon(Nach);

Print(Nach);

end;

10: Begin

writeln('Использовать PrintF(Nach,S1)');

PrintF(Nach,S1);

end;

11: Begin

writeln(' Использовать sort(Nach); Print(Nach)');

print(Nach);

sort(Nach);

print(Nach);

end;

End;

writeln;writeln('Нажми любую клавишу, кроме Enter');

repeat key:=readkey until key<>#13;

Until Y=1;

End.



Создание списка путем добавления элемента в конец.

Использовать DobKon(Nach);Print(Nach)

Введите число,признак конца 999 1

Введите число,признак конца 999 4

Введите число,признак конца 999 6

Введите число,признак конца 999 2

Введите число,признак конца 999 8

Введите число,признак конца 999 11

Введите число,признак конца 999 2

Введите число,признак конца 999 5

Введите число,признак конца 999 999


______________Печать списка_________


1 4 6 2 8 11 2 5


Список окончен





Сколько раз встречается заданный элемент

Создать свою процедуру Kolich(Nach)


______________Печать списка_________


1 4 6 2 8 11 2 5


Список окончен

Введите элемент, который надо найти :2

Элемент в списке встречается 2 раз(а)



Есть ли в списке заданный элемент.

Использовать Print(Nach),Poisk(Nach,R)


______________Печать списка_________


1 4 6 2 8 11 2 5


Список окончен

Введите элемент, который надо найти :6

Элемент найден 6



Введите элемент, который надо найти :10

Элемент не найден




Склеить два списка.

Создть свою процедуру Skleika(Nach,Nach1)

Введите второй список

Введите число,признак конца 999 1

Введите число,признак конца 999 2

Введите число,признак конца 999 3

Введите число,признак конца 999 999


______________Печать списка_________


1 2 5 6 3

Список окончен


______________Печать списка_________


1 2 3

Список окончен


______________Печать списка_________


1 2 5 6 3 1 2 3

Список окончен


26



© Рефератбанк, 2002 - 2017