Next:6.2
Построение программ с процедурами и функциями
Up:6.1
Подпрограммы: процедуры и функции
Previous:6.1.9
Метод структурной индукции
(1) procedure ВВОД; begin read(X) end ВВОД;
(2) procedure ВЫВОД (X:array[1..100] of real);
var I : integer;
begin for I := 1 to 100 do write X[I] end
ВЫВОД;
(3) procedure ВВОД (Х:ВЕКТОР); var I : ИНДЕКС;
begin for I := 1 to N do read(X) end
ВВОД;
(4) procedure ЗАМЕНА (var X,Y :ВЕКТОР); var Z :
ВЕКТОР;
begin if Сумма(Х)
Сумма(Y) then
begin Z := X; X := Y; Y := Z end
end ЗАМЕНА;
(5) procedure Сумма (var X;Y;Z : real); begin X := Y + Z end Сумма;
(6) procedure Сумма (Y,Z : real, var X : real); X := Y + Z ;
(7) procedure Сумма (Y,Z : real; var X : real); begin X := Y+Z end Сумма;
(8) Real function МАКС (X,Y : integer);
begin if X
Y then write(X) else write(Y) end;
(9) function МАКС (X,Y : integer) : integer;
begin if X
Y then write(X) else write(Y) end;
(10) function ФАКТ (N:Integer):Integer;
var I : Integer;
begin ФАКТ := 1; for I := 2 to N do ФАКТ
:= ФАКТ
I end;
(11) function ПОИСК (X:Real; A:ВЕКТОР) : Boolean;
var I : ИНДЕКС;
begin for I := 1 to N do if A[I]
= X then ПОИСК := True end ПОИСК;
(12) procedure SUM (X,Y : ВЕКТОР) : ВЕКТОР;
var I : ИНДЕКС; Z : ВЕКТОР;
begin for I := 1 to N do Z[I] := X[I] +
Y[I]; SUM := Z end;
(13) procedure ПЯТЬ : Integer; begin ПЯТЬ := 5 end;
(14) procedure MULT (K,N : Integer):Integer;
begin if N
0 then MULT := K + MULT(K,N-1)
else MULT := -MULT(K,-N)
end;
(15) procedure MULT (K,N : Integer):Integer;
begin if N = 0 then MULT := 0
else if N
0 then MULT := K + MULT(K,N-1)
else MULT := -MULT(K,-N)
end;
(16) procedure Сумма (X:Real; N:Integer):Real;
var I : Integer; S:Real;
procedure POWER (X:Real; N:Integer):Real;
begin if N = 0 then POWER := 1
else POWER := X
POWER(X,N-1)
end;
procedure ФАКТ (N:Integer):Integer;
begin if N = 0 then ФАКТ := 1 else ФАКТ
:= N
ФАКТ(N-1) end;
begin S := 0; for I := 1 to N do S := S
+ POWER(X,I) / ФАКТ(I);
Сумма := S
end;
2. Укажите, для решения каких задач написаны приведенные ниже программы и какие из них не содержат ошибок (если ошибки есть, то исправьте их):
(1)
module ЧислоДнейДоРождества;
type МЕСЯЦЫ = (ЯНВАРЬ, ФЕВРАЛЬ, МАРТ, АПРЕЛЬ,
МАЙ, ИЮНЬ, ИЮЛЬ, АВГУСТ,СЕНТЯБРЬ,
ОКТЯБРЬ,НОЯБРЬ,ДЕКАБРЬ);
var ДЕНЬ,ГОД,Сумма : integer;МЕСЯЦ,СЛЕДМЕСЯЦ:МЕСЯЦЫ;
procedure ЧТЕНИЕДАТЫ (var ДЕНЬ :Integer;
var МЕСЯЦ : МЕСЯЦЫ; var ГОД : Integer);
function ПРЕОБРАЗОВАНИЕ
(НОМЕРМЕСЯЦА :Integer;
МЕСЯЦЫ;
begin case
НОМЕРМЕСЯЦА of
end1:return ЯНВАРЬ;
2:return ФЕВРАЛЬ;
3:return МАРТ;
4:return АПРЕЛЬ;
5:return МАЙ;
6:return ИЮНЬ;
7:return ИЮЛЬ;
8:return АВГУСТ;
9:return СЕНТЯБРЬ;
10:return ОКТЯБРЬ;
11:return НОЯБРЬ;
12:return ДЕКАБРЬ
(2)
module ПоискМиниМакс;
const N = 20;
type ВЕКТОР = array
N of integer;
var A : ВЕКТОР; I,M
: integer;
procedure МИНИМАКС
(var B : ВЕКТОР);
var I : integer; MIN,MAX : integer;
procedure ЗАМЕНА (X,Y : integer);
begin if X
MAX then MAX := X end;
if Y
MIN then MIN := Y end
end;
begin MIN := B[1]; MAX
:= MIN; I := 2;
while I
N do
if B [I]
B [I+1] then ЗАМЕНА(В[I], B[I+1])
else ЗАМЕНА (B[I+1], B[I])
end;
if I = N then
if B[N]
MAX then MAX := B[N]
elsif B[N]
MIN then MIN := B[N]
end;
writeln ('MIN=', MIN, 'MAX=', MAX)
end
end
end;
procedure ВВОД (В:ВЕКТОР);
var I : integer;
begin write ('ИСХОДНЫЙ
ВЕКТОР:');
for I := 1 to N do read(B[I]); write(B[I]:5)
end;
writeln
end;
begin ВВОД(А); МИНМАКС(А); writeln('ИСХОДНЫЙ ВЕКТОР:');
for I := 1 to N do Read(M);
A[I] := A[I] + M;Write(A[I]:5) end;
МИНМАКС(А)
end ПоискМиниМакс.
(3) module УстойчивыеБраки;
const N = 10;
type МУЖЧИНЫ = integer; ЖЕНЩИНЫ = integer,
РАНГ = integer;
var M:МУЖЧИНЫ; W:ЖЕНЩИНЫ; R:РАНГ;
WMR : array N, N of ЖЕНЩИНЫ;
MWR : array N, N of МУЖЧИНЫ;
RMW : array N, N of РАНГ;
RWM : arrayN, N of РАНГ;
X : array N of ЖЕНЩИНЫ;
Y : array N of МУЖЧИНЫ;
ОДНА : array N of boolean;
procedure ПЕЧАТЬ;
var M: МУЖЧИНЫ; RM,RW
: Integer;
begin RM := 0; RW := 0;
for M := 1 to N do
write (X[M]:4);
RM := RM + RMW[M,X[M]]; RW := RW + RWM[X[M],M];
end;
writeln (RM:8, RW:4)
end;
procedure ПОПЫТКА (M:МУЖЧИНЫ);
var R:РАНГ; W:ЖЕНЩИНЫ;
procedure УСТОЙЧИВЫЙ:Boolean;
var RM:МУЖЧИНЫ; RW:ЖЕНЩИНЫ; I,K : РАНГ; F:Boolean;
begin F := True;
I := 1;
while (I
R) & F do
RW := WMR[M,I]; I := I+1;
if not ОДНА [RW] then F := RWM[RW,M]RWM[RW,Y[RW]]
end
end;
I := 1; K := RWM[W,M];
while (I
K) & F do
RM := MWR[W,I]; I := I+1;
if RM
M then S := RMW[RM,W]
RMW[RM,X[RM]]
end;
return F
end;
begin for R := 1 to N do
W := WMR [M,R];
if ОДНА [W] then
if УСТОЙЧИВЫЙ then
X[M] := W; Y[W] := M; ОДНА [W] := False;
if M
N then ПОПЫТКА (Succ(M)) else ПЕЧАТЬ end;
ОДНА [W] := True
end
end
end
end
begin
for M := 1 to N do for
R := 1 to N do read(WMR[M,R]); RMW[M,WMR[M,R]] := R end
end;
for W := 1 to N do for
R := 1 to N do read(MWR[M,R]); RWM[W,MWR[W,R]] := R end
end;
for W := 1 to N do ОДНА[W]
:= true end;
ПОПЫТКА(1)
end УстойчивыеБраки.
3. Рассмотрим следующее доказательство того, что для любого положительного числа :
Доказательство проводится методом математической индукции.
Базис. Для утверждение справедливо, ибо
Индуктивный переход. Предположим, что формула справедлива для любого , т.е.
и рассмотрим формулу для :
=
(по индуктивному предположению) =
=
=
=
=
=
=
Таким образом, утверждение справедливо и для .
Хотя доказательство выглядит как будто правильно, оно неверно, поскольку при имеем
= = = = =
Найдите ошибку в приведенных выше рассуждениях.
4. Найдите ошибку в следующем доказательстве методом математической индукции (по -- числу людей в группе) того, что в любой группе людей все люди одного роста.
Базис. Для это высказывание очевидно.
Индуктивный переход. Предположим, что высказывание справедливо для любой группы из человек, и рассмотрим произвольную группу, состоящую из человека. Произвольным образом занумеруем людей в группе и проведем следующие рассуждения. Если мы удалим ()-го человека из группы, то останется группа из человек; по индуктивному предположению все люди в такой группе одного роста. Представим себе, что вместо последнего мы удаляем первого человека из исходной группы; здесь то же число людей и, следовательно, все они одного роста. Отсюда следует, что все человек исходной группы будут одного роста, так как известно, что люди с номерами от 1 до одного роста, а ()-й человек того же роста, что и -й (даже больше, его рост совпадает с ростом второго, третьего и т.д.). Таким образом, мы показали справедливость индуктивного перехода.
5. Рассмотрим следующую функцию
procedure S (M,N : Integer):Integer;
begin
if M = 1 then if N = 1 then S := 5 else
return S(1,N-1)+2
elsif N = 1 then S := S(M-1,N)+2 else return
S(M,N-1)+2
end.
Покажите, что для любых A и B вычисление S(A,B) заканчивается и .
6. Рассмотрим следующую функцию
procedure F (M,N : INTGER):Integer;
begin if N = 0 then if M = 0 then
return 0 else return F(M - 1,N)+1 else return
F(M,N - 1) - N
end.
Докажите, что для любых неотрицательных целых чисел и вычисление заканчивается с результатом, равным значению .
7. Для функции
procedure T (M,N : integer):integer;
begin
if N = 0 then if M = 0 then return
1 else return T(M-1,N)+M else return T(M, N-1)+N
end
end
напишите общую формулу для , где и -- произвольные неотрицательные целые числа, и докажите ее справедливость.
8. Приведенные ниже три рекурсивных определения функции были запрограммированы таким образом, чтобы для любых двух неотрицательных чисел и X
однако в них были допущены ошибки. Попытайтесь доказать их правильность и выявите этапы, где доказательство не проходит. Обнаружив ошибку в таком доказательстве, найдите некоторые значения (значение) аргументов, при которых функция дает неверный ответ.
(1) procedure F (X1,X2 : integer):integer;
begin if X2 = 0 then return X1 elsif
X1 = 0 then return F(X1-1,1) else return F(F(X1-1,X2),
X2-1) endend
F;
(2) procedure F (X1, X2 : integer):integer;
begin if X2 = 0 then return 1 elsif
X1 = 0 then return F(X2-1,1) else return F(F(X1-1,X2)
X2-1) endend F;
(3) procedure F (X1,X2 : integer):integer;
begin if X2 = 0 then return X1 elsif
X1 = 0 then return F(1,X2-1) else return F(F(X1-1,X2),X2)
end
end F.
Next:6.2
Построение программ с процедурами и функциями
Up:6.1
Подпрограммы: процедуры и функции
Previous:6.1.9
Метод структурной индукции