Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Вопросы для проверки знаний. SetLength(a,0); SetLength(b,0); {Удаление динамических массивов a и b}




...

SetLength(a,0); SetLength(b,0); {Удаление динамических массивов a и b }

end. {конец тела внешней программы}

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

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

а) ввод с клавиатуры числа строк n и столбцов m целочисленной матрицы M[1..n,1..m],

б) ввод с клавиатуры элементов матрицы M[1..n,1..m],

в) формирование с помощью отдельной процедуры SUM_STR вектора S[1..n], состоящего из сумм элементов в строках матрицы,

г) вывод вектора S[1..n] на экран,

д) удаление всех динамических массивов программы.

Решение. Обозначим номера строк и столбцов матрицы через i и j, динамический линейный массив, соответствующий ей, через LM. Функция k = k (i, j, m)для расчета номеров коэффициентов LM по коэффициентам матрицы и числу столбцов взята из примера 5 п.8.5. Число столбцов матрицы m передается в процедуру суммирования элементов строк SUM_STR по двум причинам: для использования в функции k (i, j, m) и для расчета числа строк n (чтобы не передавать его через заголовок процедуры). При задании номеров элементов необходимо учитывать, что в матрице начало отсчета индексов с 1, а в динамических массивах – с 0.

var LM: array of integer; { Описание дин. массиваLM }

S: array of integer; { Описание дин. массиваS }

n,m,i,j,el: integer;

function k(i,j,m:integer):integer; {функция для расчета k = k (i, j, m) = (i-1)m +(j-1) }

begin k:= (i-1)*m + j -1; end;

procedure SUM_STR(L:array of integer; m:integer; var STR_S:array of integer);

{процедура для расчета вектора из сумм элементов в строках матрицы }

var k,n,i_first,i_fin,i,j:integer;

begin {начало тела процедуры SUM_STR }

i_first:=Low(L);i_fin:=High(L); {определение границ массива L }

n:=(i_fin-i_first+1) div m; {определение количества строк n в матрице, соответствующей динамическому массиву L }

for i:=1 to n do STR_S[i-1]:=0; {начальная инициализация массива STR_S нулями}

for i:=1 to n do {расчет элементов массива STR_S }

for j:=1 to m do

begin k:=(i-1)*m+j-1; STR_S[i-1]:=STR_S[i-1]+L[k] end;

end; {конец тела процедуры SUM_STR }

begin { начало тела основной программы}

writeln (' Vvedite сhislo strok:');read(n); {запрос и ввод числа строк n }

writeln (' Vvedite сhislo stolbtsov:');read(m); {запрос и ввод числа строк m}

SetLength (LM,n*m); { Создание динамического массиваLMдля ввода матрицы M[1..n,1..m] }

SetLength (S,n); { Создание динамического массиваSдля сумм элементов в столбцах матрицы }

for i:=1 to n do {ввод элементов матрицы с клавиатуры}

for j:=1 to m do begin

writeln('vvedite element M[',i,',',j,']='); {запрос на ввод элемента M [i,j] }

read(el); LM[k(i,j,m)]:=el; {ввод элемента M [i,j] в линейный массив LM }

end;

for i:=1 to n do begin {вывод матрицы M[1..n,1..n] на экран}

for j:=1 to m do write(' M[',i,',',j,']=',LM[k(i,j,m)]:6); {вывод строки}

writeln; {переход на очередную строку}

end;

SUM_STR(LM, m, S); {вызов процедуры SUM_STR }

for i:=0 to n-1 do { Печать динамического массиваS }

writeln(' Sum of elements in stroke ',i+1,'=',S[i]:6);

SetLength(LM,0); SetLength(S,0); //Удаление динамических массивов LM и S

end. {конец тела основной программы}

Таким образом, рассмотрены два способа передачи массивов в подпрограммы: 1) с объявлением (описанием) типа массива в вызывающем блоке и 2) с использованием открытых массивов. Применение открытых массивов позволяет создавать подпрограммы, обрабатывающие линейные массивы различной длины без дополнительного описания типа массивов в вызывающем блоке и передачи длины массива в качестве параметра подпрограммы. Через входной параметр, являющийся открытым массивом, в подпрограмму могут быть переданы как статические, так и динамические массивы. Для передачи через открытый массив многомерных массивов переменных размеров могут быть использованы те же методы, что и для организации многомерных динамических массивов.

1. Как передают в подпрограммы статические массивы постоянного размера с использованием описания их типа в вызывающем блоке?

2. Как передают в подпрограммы статические массивы ограниченного размера с использованием описания их типа в вызывающем блоке?

3. Где и с какой целью применяют открытые массивы?

4. Какие ограничения снимает использование открытых массивов в случае передачи в подпрограммы массивов различного размера?

5. Какие ограничения снимает передача через открытые массивы динамических массивов по сравнению со статическими?

6. Можно ли использовать открытые массивы для передачи многомерных динамических массивов переменных размеров?

Практические задания.

1. Разработать варианты а) - г) программы, в которой производится ввод с клавиатуры двух векторов `a = (a 1,..., an) и `b = (b 1,..., bn) и последующий расчет их скалярного произведения (`a, `b) = (a 1 b 1 +...+ anbn) с помощью отдельной функции Sc (`a, `b):

а) с использованием для векторов `a и `b статических массивов постоянной длины n =3 и опиcания типа массива в вызывающем блоке;

б) с использованием для векторов `a и `b статических массивов переменной длины 1 ≤ n ≤ 100 и опиcания типа массива в вызывающем блоке;

в) с использованием для векторов `a и `b статических массивов переменной длины 1 ≤ n ≤ 100 и открытых массивов в заголовке кода функции Sc (`a, `b);

г) с использованием векторов `a и `b произвольной длины n, динамических массивов в вызывающем блоке и открытых массивов в заголовке кода функции Sc (`a, `b).


 

Пока же рассмотрим примеры решения типовых задач.

1. Заданы вектора A и B, содержащие по 5 элементов. Используя подпрограмму, найти их скалярное произведение по формуле

Поиск скалярного произведения реализуем в виде подпрограммы-функции scal.

type vector=array [1..5] of real;

 

function scal (n:integer;

var a,b:vector):real;

var i:integer;

s:real;

begin

s:=0;

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

scal:=s;

end;

 

var i:integer;

a,b:vector;

s:real;

begin

writeln ('Вектор 1 из 5 элементов:');

for i:=1 to 5 do read (a[i]);

writeln ('Вектор 2 из 5 элементов:');

for i:=1 to 5 do read (b[i]);

s:=scal(5,a,b);

writeln ('s=',s:10:3);

end.

2. Сформировать по введенному с клавиатуры вектору A размерности n вектор res, компонентами которого являются отклонения элементов A от их арифметического среднего (подобная задача уже решалась выше, расширим ее на случай вектора).

Задача предполагает написание, по меньшей мере, двух подпрограмм: функция Middle будет вычислять арифметическое среднее элементов вектора, а процедура Otkl - формировать по вектору A и ранее найденному среднему mid искомый вектор отклонений b. Компоненты вектора b при этом будут вычисляться по формуле. Поскольку о размерности векторов в задаче ничего не сказано, укажем в разделе type максимальную размерность, равную 100 элементам.

type vector= array [1..100] of real;

 

function Middle (n:integer;

var a:vector):real;

var j:integer;

res:real;

begin

res:=0.0;

for j:=1 to n do res:=res+a[j];

Middle:=res/n;

end;

 

procedure Otkl (n:integer; mid:real;

var a,b:vector);

var j:integer;

begin

for j:=1 to n do b[j]:=abs(a[j]-mid);

end;

 

var a,res: vector;

i,n:integer;

s:real;

begin

write ('Размерность? ');

readln (n);

for i:=1 to n do begin

write ('A[',i,']=');

readln (a[i]);

end;

s:=Middle (n,a);

Otkl (n,s,a,res);

for i:=1 to n do

writeln ('res[',i,']=',res[i]:8:2);

end.

3. Используя подпрограмму, написать и проверить программу перемножения двух матриц.

Как известно, матрица A размерностью n3m может быть умножена на матрицу B размерностью m3p по следующей формуле: где ci,j -- элемент получающейся в результате перемножения матрицы С размерностью n3m. Из формулы видно, что для умножения двух матриц нам понадобится тройной цикл: внешний цикл по i перебирает строки матрицы A, вложенный в него цикл по j выбирает в матрице B очередной столбец, а самый внутренний цикл по l умножает строку матрицы A на столбец матрицы B, получая элемент ci,j. Напишем соответствующую процедуру mmul и тестовую программу для нее:

type matrix=array[1..10,1..10] of real;

 

var a,b,c: matrix;

i,j,n,m,p: integer;

 

procedure mmul (n,m,k:integer;

var a,b,c:matrix);

var i,j,l:integer; s:real;

begin

for i:=1 to n do

for j:=1 to k do begin

s:=0;

for l:=1 to m do s:=s+a[i,l]*b[l,j];

c[i,j]:=s;

end;

end;

 

begin

repeat

writeln;

write ('Введите количество строк ',

'1 матрицы: ');

readln (n);

write ('Введите количество столбцов ',

'1 матрицы: ');

readln (m);

write ('Введите количество столбцов ',

'2 матрицы: ');

readln (p);

until (n>1) and (n<11) and (m>1)

and (m<11) and (p>1) and (p<11);

for i:=1 to n do begin

writeln ('Введите строку ',i,

' матрицы A из',m,'элементов:');

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

end;

for i:=1 to m do begin

writeln ('Введите строку ',i,

' матрицы B из',p,'элементов:');

for j:=1 to p do read (b[i,j]);

end;

 

mmul (n,m,p,a,b,c);

for i:=1 to n do begin

writeln;

for j:=1 to p do write (c[i,j]:10:3);

end;

end.

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

5. В качестве еще одного развернутого примера на использование массивов в подпрограммах, разберем следующую задачу.

Имеется N городов, между которыми налажены пассажирские перевозки. Между какими городами самый активный пассажиропоток?

Количество городов обозначим константой cities. После математической формализации задачи, нетрудно заметить, что перевозки из города i в город j могут быть занесены в элемент матрицы ai,j, таким образом, требуется определить величину max(ai,j+aj,i), учитывая перевозки "туда" и "обратно". Для поиска максимального пассажиропотока достаточно двойного цикла с переменной границей по счетчику вложенного цикла. Как и в других программах, выделим в отдельные подпрограммы также типовые задачи ввода и вывода матрицы, а также ввода вещественного значения с контролем допустимых числовых границ ввода.

const cities=10;

type matrix=array [1..cities,1..cities]

of integer;

 

function max1 (n:integer; var a:matrix;

var imax,jmax:integer):integer;

var i,j,m,p:integer;

begin

m:=a[1,2]; imax:=1; jmax:=2;

for i:=1 to n do

for j:=1 to n do

if (i<>j) then begin

p:=a[i,j]+a[j,i];

if p>m then begin

m:=p; imax:=i; jmax:=j;

end;

end;

max1:=p;

end;

 

function readNumber (s:string;

min,max:integer):integer;

var a:integer;

begin

repeat

write (s);

{$I-}readln(a);{$I+}

if IoResult<>0 then

writeln ('Ошибка, введено не число!')

else if (a<min) or (a>max) then

writeln ('Ошибка, введенное число ',

'принадлежит интервалу [',min, ',',

max, ']')

else break;

until false;

readNumber:=a;

end;

 

procedure readMatrix1 (var n:integer;

var a:matrix);

var i,j:integer; s,s1:string;

begin

n:=readNumber ('Введите число строк ',

'и столбцов матрицы: ',2,cities);

for i:=1 to n do

for j:=i+1 to n do begin

s:='A['; str(i,s1); s:=s+s1+',';

str(j,s1); s:=s+s1+']=';

a[i,j]:=readNumber (s,0,maxInt);

end;

end;

 

procedure writeMatrix1 (s:string;

n:integer; var a:matrix);

var i,j:integer;

begin

writeln (s);

for i:=1 to n do begin

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

writeln;

end;

end;

 

var a:matrix;

n,gorod1,gorod2:integer;

 

begin

readMatrix1 (n,a);

max1 (n,a,gorod1,gorod2);

writeMatrix1 ('A=',n,a);

writeln ('Самый большой пассажиропоток ',

'между городами ',gorod1,' и ',gorod2);

readln;

end.

 




Поделиться с друзьями:


Дата добавления: 2014-01-06; Просмотров: 397; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.008 сек.