Paskal_ucheb_posob_ch1_21_11_2011
.pdf91
Упражнение 52.
Написать программу, которая упорядочивает по неубыванию три массива разной длины (10, 5 и 8) и выводит их на печать. Эти упорядоченные массивы используются для построения массива с минимальной длиной - [5]. Новый массив образуется путем перемножения соответствующих компонентов упорядоченных массивов.
PROGRAM MASSIVS(INPUT,OUTPUT);
TYPE A=ARrAy[1...20] OF real;
VAR x, y, z, REZ : A;
I, J: INTEGER;
PROCEDURE WWOD(K: INTEGER; VAR M:A);
VAR J: INTEGER;
BEGIN WRITELN ('ввод эл.массива');
FOR J:=1 TO K D0 READ(M[J]);
END;
PROCEDURE UP(K: INTEGER; VAR M:A);
VAR I,J:INTEGER; C:REAL;
BEGIN
FOR J:=K DOWN TO 2 do
FOR I:1 TO j-1 DO
IF M[I]>M[I+1] THEN BEGIN
C:=M[I+1];
M[I+1]:=M[I];
M[I]:=C;
END;
END;
PROCEDURE WUWOD(K:INTEGER;VAR M:A);
VAR J:INTEGER;
BEGIN
FOR J:=1 TO K DO
WRITE(M[J],’’);
End;
BEGIN
WWOD(10, x);
WWOD(5, y);
92
WWOD(8, z);
UP (10, x);
UP (5, y);
UP (8, z);
WRITELN('массивы после упорядоч.');
WuWOD(10,x);
WuWOD(5,y);
WuWOD(8,z);
FOR I=1 TO 5 DO
REZ[I]:=x[I]*y[I]*z[I]
WUWOD(5, REZ)
END.
Упражнение 53.
Написать программу, которая вводит вещественные значения аргументов x и y, а также вычисляет
F(x,y) = (x + y) -5 - (x - 2y) 3 ;
при этом возведение в степень описывает функция STEP, где а - вещест., b - целая степень.
PROGRAM FxySTEP(INPUT,OUTPUT);
VAR x,y,Fxy:REAL;
FUNCTION STEP(A : REAL, B : INTEGER) : REAL;
VAR RAB : REAL; ABSB : INTEGER;
BEGIN
RAB:=1; ABSB:=ABS(B);
WHILE ABSB>0 DO
BEGIN
RAB:=RAB*A;
ABSB:=ABSB-1;
END;
if b<0 then rab:=1/rab; STEP:=RAB;
END;
BEGIN
93
WRITELN('ввод данных');
READLN(x,y);
Fxy:=STEP(x+y,-5)-STEP(x-2*y,3);
WRITELN(Fxy);
END.
94
Лекция 13. Часть 2. Рекурсивные процедуры и функции.
Рекурсивные процедуры и функции.
Процедуры и функции в Паскале допускают рекурсию прямую и косвенную, т. е. процедура (функция) может вызвать сама себя или другую процедуру (функцию).
Если возникает необходимость в обращении к процедуре (функции) раньше, чем она описана, то в этом случае заголовок этой процедуры (функции) должен быть предварительно описан с ключевым словом FORWARD следующим образом:
PROCEDURE P (< формальные параметры >):FORWARD;
PROCEDURE Q < описание Q >;
Здесь P - имя процедуры. Такое описание указывает транслятору, что описание самой процедуры P помещено ниже (после) описания процедуры Q. В этом случае допускается в теле процедуры использовать обращение (вызов) к процедуре P.
ВНИМАНИЕ! Параметры (формальные) процедуры P указываются только в описании заголовка с FORWARD. В заголовке описания самой процедуры P (помещѐнного после Q) параметры опускаются.
Пример рекурсии.
PROCEDURE P(C:T1):FORWARD; PROCEDURE Q(H:T2);
BEGIN
........
P(A)
........
END; PROCEDURE P;
BEGIN
........
Q(B)
........
END;
95
Упражнение 54.
Описать рекурсивную функцию pow(x,n) от вещественного х (х<>0) и целого n, которая вычисляет величину
X n согласно формуле:
1, при n=0;
1/ exp(abs(n)*ln(x)) , при n<0; X n = x*(exp(ln(x)*(n-1))) , при n>0.
Function pow (x:real; n:integer): real; Begin
if n=0 then pow:=1 else
if n<0 then pow:=1/pow(x,abs(n)) else pow:=x*pow(x,n-1)
end.
Пример:
a)2-3 ,т.е. x=2; n=-3:
pow:=1/pow(2, -3 ) = 1/ pow:=1/(2*pow(2,2)) pow:=1/(2*2*pow(2,1))=1/(4*pow(2,1))
pow:=1/(4*2*pow(2,0))=1/(8*pow(2,0))=1/(8*1)=1/8
8
b) 2 ; x=2; n=8 : pow:=2*pow(2,7) pow:=2*[2*pow(2,6)]=4*pow(2,6)
pow:=2*[2*[2*pow(2,5)]]=8*pow(2,5)
pow:=2*2*2*2*pow(2,4)=16*pow(2,4)
pow:=2*2*2*2*2*pow(2,3)=32*pow(2,3)
pow:=2*2*2*2*2*2*pow(2,2)=64*pow(2,2)
pow:=2*2*2*2*2*2*2*pow(2,1)=128*pow(2,1)
pow:=2*2*2*2*2*2*2*2*pow(2,0)=256*pow(2,0)+256*1=256
96
Упражнение 55
Задачу и рассказ придумал математик Э.Люка в 1853г.
В центре мира в вершинах равностороннего треугольника в землю
вбиты 3 алмазных шпиля. На одном из них надето 64 |
золотых диска |
||||
убывающих радиусов. (Самый большой - нижний). Трудолюбивые |
буд- |
||||
дийские монахи день и ночь переносят диски с одного шпиля |
на |
дру- |
|||
гой. При этом диски надо переносить по одному и нельзя класть |
боль- |
||||
шой диск на меньший. |
Когда все |
диски перенесут на другой шпиль, |
|||
наступит конец света. |
Оставляя |
временно вопрос о конце |
света, по- |
||
ищем алгоритм для перенесения всех дисков с одного шпиля |
на другой. |
||||
Что это не так просто, вы можете убедиться, изготовив |
модель ханой- |
||||
ских башен и поупражнявшись с ними. |
|
|
|
Идея рекурсивного алгоритма не вызывает трудностей. Если алгоритм P(m,a,b,c) должен перенести верхние 'm' дисков со шпиля "а" на шпиль "б", то (в предположении, что все диски лежат правильно - меньший на большем и что остальные диски на всех трех шпилях не меньше, чем верхние "м" на шпиле "а") легко пишем алгоритм P(m,a,b,c) если m=1, то перенести верхний диск со шпиля "а" на шпиль "в" иначе P(m-1,a,b,c); P(1,a,b,c);P(m-1,c,b,a).
"По человечески" этот алгоритм очень понятен. Если м=1,то перенести один диск с "а" на"в". Если же m>1, то перенести временно m-1 верхних дисков с "а" на "с". Потом перенести один оставшийся диск с "а" на "в" и,наконец, перенести m-1 дисков, хранящихся на "с", на шпиль "в". Что касается перенесения m-1 дисков, то для этого подойдет тот же алгоритм, но с уменьшенным (от "м" до м-1) числом переносимых дисков. Т.о., мы перейдем от м к м-1, от м-1 к м-2,м-3 ... и дойдем до 1.
Чтобы записать этот алгоритм на Паскале, обозначим шпили а,в,с цифрами 0,1,2 и будем печатать нужные переносы дисков. Перенос со шпиля "а" на "в" будет изображаться надписью 0->1, с "в" на "с" - надписью 1->2 и т.д.
Program Hanoy; Var n:integer;
Procedure p(m,a,b,c:integer); Begin
if m=1 then write(a,'->',b,' ') else
begin p(m-1,a,c,b); p(1,a,b,c); p(m-1,c,b,a);
97
end;
End;
Begin
writeln('Введите число дисков'); readln(n);
writeln('n=',n);
p(n,0,1,2);
End.
При n=4 эта программа напечатает
0->2 0->1 2->1 0->2 1->0 1->2 0->2 0->1 2->1 2->0 1->0 2->1 0->2 0->1 2->1