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

Podprogram

.pdf
Скачиваний:
9
Добавлен:
01.04.2015
Размер:
117.64 Кб
Скачать

Лабораторная работа №6

Процедуры и функции, рекурсия

Упражнения

1.type natur = 1..maxint; var m,n: natur;

function NOD(a,b: natur): natur; begin

while a<>b do

if a>b then a:=a-b else b:=b-a;

NOD:=a

end;

Определить, что будет выдано на печать после выполнения следующих операторов и объяснить почему:

m:=8; n:=6; writeln(NOD(m,n),m,n);

2.Указать ошибки в описании функции:

a)function f(a:’a’..’z’):integer; begin f:=ord(a)-ord(’p’);

if f<0 then f:=-f

end;

б) function g(k:integer):0..maxint; var i,s:0..maxint;

begin s:=0;

for i:=1 to k do s:=s+sqr(i);

end;

в) function h(x:integer):integer; var i,s:0..maxint;

begin h(x):=(sqr(x)+x)/2 end;

3.var c,d: integer; procedure P(x,y: integer); begin y:=x+1 end;

procedure Q(x: integer; var y: integer); begin y:=x+1 end;

procedure R(var x,y: integer); begin y:=x+1 end;

a) для каждой из процедур указать, какие из параметров являются параметрамизначениями, а какие – параметрами-переменными;

б) определить, что будет выдано на печать:

1

c:=2; d:=0; P(sqr(c)+c,d); writeln(d); c:=2; d:=0; Q(sqr(c)+c,d); writeln(d);

в) допустимы ли обращения: R(sqr(c)+c,d) и R(c,d)?

4.Пусть процедура sokr(a, b, p, q) от целых параметров (b ≠ 0) приводит дробь a/b к несократимому виду p/q.

a)какие из параметров этой процедуры обозначают исходные данные для нее,

акакие – результаты? Какие параметры следует объявить параметрамизначениями, а какие – параметрами-переменными?

б) допустимы ли обращения sokr(k+1, 14, n, 7) и sokr(k, sqrt(k), k, n), где k и n – целые переменные?

5.Пусть процедура maxmin(x, y) присваивает параметру x большее из вещественных чисел x и y, а параметру y – меньшее.

a)какие из параметров этой процедуры обозначают исходные данные для нее,

акакие – результаты? Какие параметры следует объявить параметрамизначениями, а какие – параметрами-переменными?

б) допустимы ли обращения maxmin(5.2, sin(z)) и maxmin(z, k), где z – вещественная переменная, а k – целая?

6.Какие из следующих описаний функции f(n), которая должна вычислять факториал от n, правильны?

а) function f(n:integer):integer; begin f:=n*f(n-1) end;

б) function f(n:integer):integer;

begin if n=0 then f:=1 else f:=f(n+1)/(n+1) end; в) function f(n:integer):integer;

begin if n=0 then f:=1 else f:=n*(n-1)*f(n-2) end; г) function f(n:integer):integer;

begin if n=0 then f:=1 else f:=n*f(n-1) end;

7.function f(n:integer):integer;

begin if n>100 then f:=n-10 else f:=f(f(n+11)) end;

Вычислить f(106), f(99) и f(85). Какие вообще значения принимает эта функция?

Примеры решения задач

Пример 1. По заданному вещественному числу x вычислить величину

sh(x) · tg(2x + 1) tg2(1 + sh(x + 1)).

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

2

Var x,y:real;

function sh(x:real):real; {гиперболический синус} begin

sh:=0.5*(exp(x)-exp(-x)) end; {sh}

function tg(x:real):real; {тангенс} begin

tg:=sin(x)/cos(x) end; {tg}

begin {основная программа} write(’x=’); readln(x);

y:=sh(x)*tg(2*x+1)-sqr(tg(1+sh(x+1))); writeln(’y=’,y:10:3);

end.

Пример 2. Определить площадь фигуры, составленной из треугольников

Решение. Если обозначить площадь фигуры за S, а площади треугольников, из которых он составлен, за S1, S2 и S3 соответственно, то искомая площадь S = S1 + S2 + S3. Опишем функцию, вычисляющую площадь треугольника со сторонами

a, b и c по формуле Герона:

S= p(p − a)(p − b)(p − c), где – полупериметр.

В основной программе вызовем эту функцию трижды: сначала вычисляем площадь первого треугольника со сторонами a = 3, b = 4 и c = 2.1, затем площадь второго треугольника со сторонами a = 4, b = 2 и c = 2.5, и, наконец, площадь третьего треугольника со сторонами a = 2, b = 2.5 и c = 1. Затем суммируем полученные площади.

var S1,S2,S3,S: real;

function S_tr(a,b,c: real): real; {площадь треугольника по формуле Герона} var p: real; {полупериметр}

begin p:=(a+b+c)/2;

S_tr:=sqrt(p*(p-a)*(p-b)*(p-c)) end;

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

S1:=S_tr(3,4,2.1); S2:=S_tr(4,2,2.5); S3:=S_tr(2,2.5,1); S:=S1+S2+S3;

writeln(’S=’,S:10:3);

end.

3

Пример 3. Дан массив целых чисел a1, a2, ..., an. Найти

min(ai) + max(ai).

i

i

Решение. Для поиска как максимального, так и минимального элементов в массиве используем функции.

Const n=5;

Type vek=array [1..n] of integer; Var a: vek; i,x: integer;

function maxvek(a:vek):integer; {максимум} var i,r: integer;

begin r:=a[1];

for i:=2 to n do

if r<a[i] then r:=a[i]; maxvek:=r;

end; {maxvek}

function minvek(a:vek):integer; {минимум} var i,r: integer;

begin r:=a[1];

for i:=2 to n do

if r>a[i] then r:=a[i]; minvek:=r;

end; {minvek}

Begin {основная программа} for i:=1 to n do

begin write(’a[’,i,’]=’); readln(a[i]) end; x:=minvek(a)+maxvek(a); writeln(’max+min=’,x);

end.

Пример 4. Даны два двумерных массива целых чисел {aij }ni;j=0 и {bij}ni;j=0. Опре-

делить, в каком из этих массивов больше сумма элементов.

Решение. Ввод массива оформим в виде процедуры, а вычисление суммы элементов массива – в виде функции.

Type m=array [0..10,0..10] of integer; Var a,b: m; n,sa,sb: integer;

procedure input(name:char; var mas:m; n:integer); var i,j:integer;

begin

writeln(’Введите матрицу ’,name,’:’) {name - имя массива (А или В)} for i:=0 to n do

begin

for j:=1 to n do read(mas[i][j]); readln;

4

end;

end;

function sum(mas:m; n:integer):integer; var i,j,s:integer;

begin s:=0;

for i:=0 to n do

for j:=0 to n do s:=s+mas[i][j]; sum:=s;

end; Begin

write(’n=’); readln(n); input(’A’,a,n); input(’B’,b,n); sa:=sum(a,n); sb:=sum(b,n);

if sa>sb then writeln(’Сумма элементов больше в матрице A’) else

if sa<sb then writeln(’Сумма элементов больше в матрице B’) else writeln(’Суммы элементов равны в обеих матрицах’);

end.

Пример 5. Даны две действительные матрицы размером n×n. Написать программу умножения матрицы на матрицу.

Решение. Ввод/вывод матрицы, умножение матрицы на матрицу оформим в виде процедур.

Const n=3;

Type matr=array [1..n,1..n] of real; Var a,b,c: matr; i,j: integer; Procedure input(name:char; var a:matr); var i,j,r:integer;

begin

writeln(’Введите матрицу ’,name,’ размером ’,n,’*’,n,’:’); for i:=1 to n do

begin for j:=1 to n do read(a[i,j]); readln;

end;

end;

Procedure print(name:char; a:matr); begin

writeln(’Матрица ’,name,’:’); for i:=1 to n do

begin for j:=1 to n do write(a[i,j]:7:2); writeln

end; end; {print}

Procedure mult(a,b:matr; var c:matr); {умножение матрицы на матрицу} var s:real; i,j,k:integer;

begin

5

for i:=1 to n do for j:=1 to n do

begin s:=0;

for k:=1 to n do s:=s+a[i,k]*b[k,j]; c[i,j]:=s;

end; end; {mult} Begin

input(’a’,a); input(’b’,b); mult(a,b,c); print(’c’,c);

end.

Пример 6. Составить рекурсивную функцию для вычисления n!. Вычислить 7!, используя данную функцию.

Решение. По определению,

{ (n

 

 

 

n! =

 

1)! n, если n > 0.

 

1,

·

если n = 0,

 

 

 

Var m: longint;

Function Fact(n: word): longint; Begin

If n=0 then Fact:=1 else Fact:=Fact(n-1)*n

end; Begin

m:=Fact(7);

write(m)

end.

Рассмотрим вызов функции m:=Fact(7). Т.к. 7>0 возникает рекурсивное обращение к функции Fact со значением параметра 6. При этом создается копия тела функции и для нового значения 6 выделяется новая переменная n. Т.к. 6>0 снова происходит обращение к функции со значением 5 и т.д., пока значение параметра не станет равно 0. Значений n будет 8 штук – локальные n сохраняются в каждой копии функции.

Пример 7. Выдать на печать в обратном порядке цифры целого положительного числа N.

Решение. Для решения данной задачи составим рекурсивную процедуру.

Var N: longint;

Procedure Reverse(N: longint);

Begin

If N>0 then

Begin Write(N mod 10);

Reverse(N div 10)

6

end

end; Begin

Write(’N=’); Readln(N); Reverse(N)

end.

Пусть N = 12345.

Т.к. 12345 > 0, то выводим на экран 5 (остаток от деления 12345 на 10), и вызываем Reverse(1234). 1234 > 0, поэтому печатается 4 и идет обращение к Reverse(123)

ит.д.

Вконце 0 не больше 0 и последняя из вызванных процедур заканчивает свою работу. Затем предпоследняя заканчивает свою работу и т.д. Однократное обращение к процедуре вызвало ее пятикратное срабатывание.

Пример 8. Упорядочить заданный одномерный массив, используя метод “быстрая сортировка”.

Решение. Сортировка методом пузырька в среднем наименее эффективна из трех алгоритмов простой сортировки. Однако неожиданно оказывается, что усовершенствование сортировки, основанной на обмене, дает вообще лучший из известных до сего времени метод сортировки массивов. Он обладает столь блестящими характеристиками, что его изобретатель К. Хоар окрестил его быстрой сортировкой.

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

Рассмотрим следующий рекурсивный алгоритм:

выберем средний элемент и обозначим его x;

просмотрим массив, двигаясь слева направо, пока не найдем элемент ai > x, а затем просмотрим его справа налево, пока не найдем элемент ai < x. Теперь поменяем местами эти два элемента и продолжим процесс “просмотра с обменом” до тех пор, пока два просмотра не встретятся где-то в середине массива. В результате массив разделится на две части: левую – с меньшими элементами чем x, и правую – с элементами большими x.

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

Const n=10;

Type v=array [1..n] of integer; Var x: v; i: integer;

Procedure swap(var a,b:integer); {обмен} var r:integer;

begin

r:=a; a:=b; b:=r; end; {swap}

7

Procedure sort(a,b:integer); {быстрая сортировка} var i,j,mid:integer;

begin

i:=a; j:=b; mid:=x[(a+b) div 2]; repeat

while x[i]<mid do inc(i); while x[j]>mid do dec(j); if i<=j then

begin

swap(x[i],x[j]); inc(i); dec(j); end;

until i>j;

if a<j then sort(a,j); if i<b then sort(i,b);

end; {sort} Begin

for i:=1 to n do

begin write(’x[’,i,’]=’); readln(x[i]) end; sort(1,n);

for i:=1 to n do writeln(’x[’,i,’]=’,x[i]); end.

8

Лабораторные задания

Задания базового уровня: 1, 2, 6, 10

1. Даны действительные числа a, b, c. Найти

1

z = g(a + b, c) + 4 g(a − b, 1.8), где g(x, y) = sin(x + y) + 5 ln(3 + y) + tg 1 + x2 .

Тест: При a = 1, b = 2, c = 3 результат будет z = 45, 2067.

2.Дан треугольник, вершины которого имеют координаты (x1, y1), (x2, y2), (x3, y3). Определить площадь треугольника, используя функцию, вычисляющую расстояние между двумя заданными точками.

3.Дано вещественное число a. Определить функцию для вычисления y = xn и вычислить значение выражения a 8 (a + 1)3 + 3a2 (степень вещественного числа с натуральным показателем вычислять через умножение).

Тест: При a = 2 результат будет равен 14, 9961.

4.Написать программу нахождения наибольшего общего делителя (НОД) трех чисел, используя функцию нахождения НОД двух чисел.

5.Составить программу определения “близнецов” среди чисел n, n + 1, ..., 2n, т.е. простых чисел, разность между которыми равна двум. Использовать функцию определения простого числа.

6.Два квадратных уравнения заданы коэффициентами a1, b1, c1, a2, b2 и c2. Определить, имеют ли уравнения вещественные корни, если да, то лежат ли оба корня первого уравнения между корнями второго.

7.Даны натуральное число n, вещественные массивы a[1..n], b[1..n]. В каждом из массивов все отрицательные элементы заменить на заданное число p.

8.Даны две вещественные квадратные матрицы порядка n. Применить к данным матрицам процедуру, печатающую элементы, равные максимальному, и их индексы.

9.Даны матрица A размерности n×n и n-элементные векторы x, y. Найти A2x+y. Здесь

x + y = (x1 + y1, x2 + y2, ..., xn + yn);

n

z = Ax, zi = ai;kxk, A2x = A(Ax).

k=1

10.Даны неотрицательные целые числа n, m. Вычислить значение биномиального коэффициента Cnm по следующей формуле:

C0

= Cn = 1; Cm = Cm

+ Cm 1

при 0 < m < n.

n

n

n

n 1

n 1

 

11.Написать рекурсивную программу вычисления суммы n первых членов геометрической прогрессии.

9

Индивидуальные задания

Решите данные задачи с использованием подпрограмм – функций или процедур. При составления алгоритмов решения задач полезным будет прежде всего найти ответы на вопросы:

Какую подзадачу приходится решать в ней несколько раз? Как следует описать решение этой подзадачи – как функцию или как процедуру? Сколько у этой функции или процедуры параметров? Каков их смысл? Можно ли решить эту подзадачу рекурсивно?

1.1.Даны координаты вершин выпуклого n-угольника в порядке их обхода по часовой стрелке. Найти площадь данного многоугольника.

Указание. Разбить многоугольник на треугольники (выбрав одну вершину многоугольника, соединить ее отрезками с остальными вершинами) и просуммировать площади треугольников.

1.2.Даны натуральное число n, вещественные массивы a[1..n], b[1..n]. Все элементы, меньшие среднего арифметического, увеличить на 10

1.3.Даны неотрицательное целое число n и действительное число x. Вычислить

величину xn согласно формуле:

 

1,

если n = 0,

xn = { xn 1 · x,

если n > 0.

2.1. Даны длины a, b и c сторон некоторого треугольника. Найти медианы тре-

угольника, сторонами которого являются медианы исходного треугольника.

Указание. Длина медианы, проведенной к стороне a, равна 0.5 2b2 + 2c2 − a2.

2.2.Пусть процедура sum(x, y, z) присваивает вектору z сумму векторов x и y. Описать эту процедуру и использовать ее для вычисления a + b + c, где a, b, c – данные 30-элементные целочисленные векторы.

2.3.Дано неотрицательное целое число n. Вычислить значение n-го числа Фибо-

наччи: {

F (n) =

1,

если n = 0 или n = 1,

F (n − 1) + F (n − 2),

если n > 1.

 

3.1.Два натуральных числа называются “дружественными”, если каждое из них равно сумме всех делителей другого, за исключением его самого (таковы, например, числа, 220 и 284). Напечатать все пары дружественных чисел, не превосходящих заданного натурального числа n.

3.2.Описать процедуру Square(A, k), которая преобразует заданный одномерный массив целых чисел A, заменяя элементы, кратные k, их квадратами.

3.3.Написать рекурсивную программу вычисления n-го члена геометрической прогрессии.

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

4.2.Описать процедуру LeftShift(A, k), которая преобразует заданный одномерный массив A, циклически сдвигая ее элементы на k позиций влево.

4.3.Написать рекурсивную программу вычисления суммы n первых членов арифметической прогрессии.

10

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