Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Задачник-практикум по основам программирования. Учебное пособие по курсу «Информатика»

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
1 Мб
Скачать

Контрольные вопросы

1)x = 2 ( ( x2 ) 2 ) 2 = 162 = 256

2)x = 3 ( ( x2 ) 2 ) 2 = 812 = 6561

Пример 8.11. Описать рекурсивную и нерекурсивную функции вы- числения значения по формуле:

1+ 2 + 3 + ... + n

Используя эти функции, вычислить значения для различных n > 3 и сравнить результаты.

program Rec_11; var n:integer;

function f_rec(n,i:integer):real; begin

if i=n then f_rec:=sqrt(n)

else f_rec:=sqrt(i+f_rec(n,i+1))

end;

function f_nrec(n:integer):real; var i:integer;

s:real; begin

s:=0;

for i:=n downto 1 do s:=i+sqrt(s);

f_nrec:=sqrt(s) end;

begin write(‘n=’); readln(n);

writeln(f_rec(n,1)); writeln(f_nrec(n))

end.

Пример 8.12. Описать рекурсивную процедуру построения узора из окружностей по правилам:

151

окружность первого уровня размещается в середине графического окна (экрана);

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

Используя эту процедуру, построить узор из окружностей уровня n = 2, 3, 4.

program Rec_12; uses GraphABC;

var x,y,r,n:integer;

procedure Elem(x,y,r,n:integer); begin

if n>0 then begin

Circle(x,y,r); Elem(x-r,y,r div 2,n-1); Elem(x+r,y,r div 2,n-1); Elem(x,y-r,r div 2,n-1); Elem(x,y+r,r div 2,n-1)

end end; begin

x:=WindowWidth div 2; y:=WindowHeight div 2; r:=y div 2;

write(‘Введите число уровней узора ‘); readln(n);

TextOut(250,0,’УЗОР ИЗ ОКРУЖНОСТЕЙ’); Elem(x,y,r,n)

end.

Результат работы программы Rec_12 приведен на рисунке 1.

На рисунке 1 изображены на самом деле не окружности, а круги, т. е. изображения следующего уровня делают невидимыми фигуры пре- дыдущих уровней.

В библиотеке GraphABC предусмотрена возможность рисова- ния «прозрачных» фигур (см. о стилях кисти в справке по PascalABC или в [18]). Для этого в программе Rec_12 перед вызовом процедуры Elem(x,y,r,n)следует добавить обращение к процедуре библиотеки

SetBrushStyle(bsClear);

152

УЗОР ИЗ ОКРУЖНОСТЕЙ

Рис. 1. Узор из окружностей. Число уровней = 3

Тогда будет установлен стиль невидимой кисти, и изображение узора будет «прозрачным», таким как на рисунке 2.

УЗОР ИЗ ОКРУЖНОСТЕЙ

Рис. 2. Узор из окружностей. Использование невидимой кисти

153

Упражнения

1)Модифицировать программу Rec_12 таким образом, чтобы каждая следующая окружность рисовалась другим цветом.

2)Модифицировать программу Rec_12 таким образом, чтобы на каждом уровне окружности рисовались своим цветом.

Пример 8.13. Вводится с клавиатуры посимвольно без ошибок выра- жение. Признак окончания ввода точка.

Вид выражения определен следующим образом: <выражение>::=<слагаемое> | <слагаемое> ± <слагаемое> <слагаемое>::=<множитель> | <множитель> * <множи-

тель> <множитель>::=<идентификатор> | (<выражение>) <идентификатор>::=<буква>

Преобразовать выражение в постфиксную форму записи. Постфиксная запись (польская инверсная запись ПОЛИЗ) – бесско-

бочная запись арифметических выражений, при которой знак операции ставится после операндов.

Примеры преобразований:

(A+B)*(C-D)

AB+CD-*

A+B*(C-D)

ABCD-*+

A+B*C-D

ABC*+D-

Преобразование реализуется с помощью процедур обработки каждой синтаксической конструкции. Так как эти синтаксические конструкции определяются рекурсивно, то соответствующие процедуры взаимно рекур- сивны.

Рекурсивный вызов может быть косвенным. В этом случае процедура обращается к себе опосредованно, путем вызова другой процедуры, в кото- рой содержится обращение к первой.

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

вать опережающее описание.

Опережающее описание подпрограммы состоит из ее заголовка, за которым идет зарезервированное слово forward.

program Rec_13;{ Иллюстрация косвенной рекурсии }

procedure Postfix;

{

Преобразование в ПОЛИЗ }

var ch: char; {хранит

символ}

154

procedure Find;

{процедура пропуска пробелов}

begin

 

 

repeat

 

 

read(ch)

 

 

until ch<>’ ‘

 

 

end;

 

{выражение}

procedure Expression;

var op: char; {знак операции}

procedure Factor; forward; {опережающее описание}

procedure Term;

{слагаемое}

begin

 

Factor;

 

while ch=’*’ do begin

Find;

Factor;

write(‘*’) {вывод *} end

end; {Term}

procedure Factor; {множитель} begin

if ch=’(‘ then begin

Find;

Expression; end

else

write(ch); {вывод буквы - идентификатора} Find

end; {Factor} begin {Expression}

Term;

while (ch=’+’) or (ch=’-’) do begin

op:=ch;

Find;

Term;

write(op) {вывод знака}

155

end

end; {Expression} begin {Postfix}

Find; write(‘ ‘); repeat

Expression until ch=’.’; writeln

end; {Postfix}

begin {основная программа} Postfix

end.

Упражнения

1)Можно ли поменять описание процедур Factor и Term местами? Необходимо ли при этом использовать опережающее описание?

2)В программе Rec_13 процедуры Factor и Term описаны внутри процедуры Expression. Сделать все три процедуры одного уровня вло- женности в процедуре Postfix.

Пример 8.14. Дано натуральное число n. Получить изображение «ковра Серпинского» n-го порядка [19].

S1 – «Ковер Серпинского» первого порядка.

S2 – «Ковер Серпинского» второго порядка

S3 – «Ковер Серпинского» третьего порядка

156

S4 – «Ковер Серпинского» четвертого порядка

«Ковер Серпинского» или кривая Серпинского i-го порядка [19] об- разуется четырьмя рекурсивными составляющими образами A, B, C, D, которые соединяются линиями, не принадлежащими рекурсивному образу. Эти замыкающие линии представляют собой отрезки прямых в четырех внешних углах. Можно считать, что они принадлежат непустой начальной кривой S0 квадрату, «стоящему» на одном своем углу.

Составляющая A четвертого порядка

Составляющие A, B, C, D по существу идентичны. Они лишь пово- рачиваются на 90°.

Составляющие A, B, C, D строятся с помощью следующих рекуррен- тных соотношений:

157

S0 : A

B

 

C

D

.

Si :для i > 0

A, B, C, D строятся следующим образом:

 

A: A

B

D

A

 

B: B

C

A

B

 

C: C

D

B

C

 

D: D

A

C

D

 

При визуализации рисунка прорисовываются только отрезки в направ- лении, заданном стрелками.

program Rec_14; { Ковер Серпинского } uses GraphABC;

var a, b, x, y, n: integer; procedure lrel (dx,dy: integer); begin

x:=x+dx; y:=y+dy; LineTo(x,y)

end;

procedure BB(k: integer); forward; procedure CC(k: integer); forward; procedure DD(k: integer); forward; procedure AA(k: integer);

begin

if k>0 then begin

AA(k-1); lrel(a,b); BB(k-1); lrel(a,0); DD(k-1); lrel(a,-b); AA(k-1)

end end;

procedure BB(k: integer); begin

if k>0 then begin

BB(k-1); lrel(-a,b); CC(k-1); lrel(0,b); AA(k-1); lrel(a,b);

158

BB(k-1) end

end;

procedure CC(k: integer); begin

if k>0 then begin

CC(k-1); lrel(-a,-b); DD(k-1); lrel(-a,0); BB(k-1); lrel(-a,b); CC(k-1)

end end;

procedure DD(k: integer); begin

if k>0 then begin

DD(k-1); lrel(a,-b); AA(k-1); lrel(0,-b); CC(k-1); lrel(-a,-b); DD(k-1)

end end; begin

n:=6; {порядок кривой} a:=3; b:=a; {длины сторон}

x:=10; y:=10; {координаты начальной точки} SetWindowCaption(‘Ковер Серпинского’); SetWindowSize(590,590);

MoveTo(x,y); AA(N); lrel(a,b); BB(N); lrel(-a,b);

CC(N); lrel(-a,-b); DD(N); lrel(a,-b)

end.

159

Упражнения

1)Получить изображение каждой из составляющих A, B, C, D по отдельности.

2)Модифицировать программу таким образом, чтобы на каждом уровне фрагменты кривых рисовались своим цветом.

3)Можно ли в программе Rec_14 избавиться от опережающего описания процедур аналогично заданию в Упражнении Примера 8.13?

4)Поменять местами описания процедур AA, BB, CC, DD. Настроить программу, чтобы она работала.

ЗАДАЧИ

8.1.Описать рекурсивную функцию C(m, n), где 0 m n, для вычисления биномиального коэффициента Cnm по следующей формуле:

Cn0 = Cnn = 1; Cnm = Cnm1 + Cnm11 при 0 < m < n.

8.2.Описать рекурсивную функцию NOD, которая возвращает наибольший общий делитель (НОД) чисел x и y.

НОД для x и y определяется рекурсивно следующим образом [20]:

а)

б)

 

x,

если y = 0

NOD(x, y) =

 

если y 0

NOD( y, x% y),

где % – операция вычисления остатка от деления нацело;

 

x,

если x = y

 

NOD(x y, y),

если x > y

NOD(x, y) =

 

 

если x < y

NOD(x, y x),

8.3.Описать рекурсивную функцию root(f, a, b, eps), которая находит приближенное значение корня заданной функции f(x) на отрезке [a, b]

методом деления отрезка пополам (описание метода см. в подразделе Задачи 7.3). Считать, что a < b, f (a) f (b) <0 и f(x) непрерывная

и монотонная функция на отрезке [ a,b ].

8.4.Функция f(n) определена для целых положительных чисел следующим образом:

160

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]