- •Содержание
- •Раздел 2.Программирование на процедурном языке turbo pascal 3
- •Раздел 2.Программирование на процедурном языке turbo pascal Лабораторная работа №1. Знакомство с интегрированной средой Turbo Pascal 7.0. Разработка первой программы.
- •Лабораторная работа № 2. Разработка программ, реализующих линейный процесс в среде Turbo Pascal 7.0.
- •Лабораторная работа № 3. Разработка программы, включающей различные форматы ввода/вывода данных средствами языка Pascal.
- •Лабораторная работа № 4. Вычисление алгебраических выражений с использованием стандартных процедур и функций языка Pascal.
- •Лабораторная работа № 5. Разработка программы для решения текстовой задачи в среде Turbo Pascal 7.0.
- •Лабораторная работа № 6. Вычисление заданного выражения при произвольных значениях переменных с использованием нескольких окон на одном экране. Работа с цветом в текстовом режиме.
- •Лабораторная работа № 7. Использование языка программирования для разработки программ вычисления математических выражений с использованием оператора if.
- •If выражение then оператор1
- •Лабораторная работа № 8. Разработка программы для решения текстовых задач, содержащих ветвление
- •Лабораторная работа № 9. Использование языка программирования для реализации разветвляющихся алгоритмов с использованием выражения – селектора в среде Turbo Pascal 7.0.
- •Лабораторная работа № 10. Разработка программ для реализации простых циклических алгоритмов средствами языка Pascal.
- •Лабораторная работа № 11. Разработка программ, включающих алгоритмы работы с числом
- •Лабораторная работа № 12. Реализация задачи табулирования функции на заданном отрезке в среде Turbo Pascal.
- •Лабораторная работа № 13. Вычисление суммы бесконечного ряда с заданной степенью точности в среде Turbo Pascal.
- •Лабораторная работа № 14. Разработка программ, включающих циклический процесс средствами языка Turbo Pascal.
- •Лабораторная работа № 15. Разработка программы реализации текстовой задачи, содержащей условия и циклы.
- •Лабораторная работа № 16. Разработка программы реализации задачи, содержащей одномерный массив данных.
- •Лабораторная работа № 17. Разработка программы реализации задачи, содержащей двумерный массив данных.
- •Лабораторная работа № 18. Методы сортировки массива в среде Turbo Pascal
- •Лабораторная работа № 19. Разработка программы работы со строками в среде Turbo Pascal
Лабораторная работа № 17. Разработка программы реализации задачи, содержащей двумерный массив данных.
Цель работы:
закрепить теоретические знания о понятии «вложенные циклы»
овладение навыками алгоритмизации структур, содержащих двумерные массивы
научиться использовать возможности языка программирования для реализации алгоритмов, содержащих двумерные массивы данных
закрепить практические навыки по составлению тестов и отладке программы
Оборудование:
программная часть – интегрированная среда Turbo Pascal 7.0
аппаратная часть - ПЭВМ IBM PC/XT
задание на выполнение работы в электронном варианте
Теоретическая часть
Двумерный массив – это одномерный массив, элементами которого являются одномерные массивы. Другими словами, это набор однотипных данных, имеющий общее имя, доступ к элементам которого осуществляется по двум индексам. Наглядно двумерный массив удобно представлять в виде таблицы, в которой n строк и m столбцов, а под ячейкой таблицы, стоящей в i-й строке и j-м столбце понимают некоторый элемент массива a[i][j].
Действительно, если разобраться с тем, что такое a[i] при фиксированном значении i, то увидим, что это одномерный массив, состоящий из m элементов, к которым можно обращаться по индексу: a[i][1], a[i][2], ... , a[i][m]. Схематически это вся i-я строка таблицы. Аналогично, если мы рассмотрим одномерный массив строк, то сможем заметить, что это так же двумерный массив, где каждый отдельный элемент – это символ типа char, а a[i] - это одномерный массив, представляющий отдельную строку исходного одномерного массива строк. Исходя из идеи определения двумерного массива, можно определить рекуррентное понятие многомерного массива:
n-мерный массив – это одномерный массив, элементами которого являются (n-1)-мерные массивы.
Несложно догадаться, что 3-мерный массив визуально можно представить в виде куба с ячейками, где каждый элемент имеет вид a[i][j][k]. А вот с большими размерностями возникают сложности с визуальным представлением, но математическая модель ясна.
По-другому, двумерный массив также называют матрицей, а в том случае, когда n=m (число строк равно числу столбцов) матрицу называют квадратной. В матрицах можно хранить любые табличные данные: содержание игрового поля (шашки, шахматы, Lines и т.д.), лабиринты, таблицу смежности графа, коэффициенты системы линейных уравнений и т.д.
Действия с двумерными массивами
Условимся, что массив а состоит из n строк и m столбцов.
• Суммирование элементов каждой строки.
Результатом является массив с именем d, состоящий из n сумм элементов строк:
for i:=l to n do
begin
s:=0;
for j:=l to m do s:=s+a[i,j] ;
d[i]:=s;
end;
Аналогично вычисляется сумма в столбцах, для этого внешний цикл необходимо сделать по переменной j (номер столбца), а внутренний — по i (номер в строке).
• Поиск минимального элемента всей матрицы.
Переменная min используется для хранения значения минимального элемента, k — номер строки, l — номер столбца, где он находится:
min:=a[1,1]; k:=1; l:=1;
for i:=1 to n do
for j:=1 to m do
if min>a[i,j] then
begin
min:=a[i,j];
k:=i; l:=j;
end;
• Умножение матрицы а на вектор x, в результате получается новый вектор у:
for i:=l to n do
begin
s:=0;
for j:=1 to m do
s:=s+a[i,j]*x[j];
y[i]:=s;
end;
Нередко при алгоритмическом решении задачи возникает необходимость создания цикла, содержащего в своем теле другой цикл. Такие вложенные друг в друга циклы относятся к структурам вложенных циклов.. Порядок вложенности циклов, когда в теле внутреннего цикла содержатся другие циклы, может быть достаточно большим. Этот порядок определяется методом, с помощью которого достигается решение поставленной задачи. Так, при обработке одномерных массивов, как правило, удается построить алгоритмическую схему без вложения циклов. Однако в ряде случаев при решении таких задач без вложенных циклов не обойтись.
Отметим, что все вложенные друг в друга циклы, включая наружный, должны иметь счетчики с различными именами. Вне этих циклов счетчики могут быть использованы как обычные переменные или как счетчики других циклов.
Алгоритм сортировки массива
Рассмотрим задачу сортировки одномерного массива Z длины N. Отсортировать массив – значит расположить его элементы в порядке роста или убывания.
Опишем метод сортировки массива в порядке роста. Сначала выполняется проход по массиву с целью определения в нем наименьшего элемента. Затем производится перестановка этого элемента с первым. Далее совершается второй проход по массиву, начиная со второго элемента. Найденный наименьший элемент переставляется со вторым и т. д. После (N-1)-го прохода с выполнением названных операций массив окажется отсортированным.
Блок-схема этого алгоритма сортировки показана на рис. 9. Она включает 12 блоков. После начала работы в блоке 2 переменная N и массив Z заполняются константами. Затем в блоке 3 проверяется условие о том, нужно ли сортировать массив. Это сводится к установлению факта наличия в массиве нескольких элементов, т. к. массив из одного элемента всегда отсортирован. Если этот факт установлен, то алгоритм приступает к сортировке. Процедура сортировки выполняется в цикле, объединяющем блоки 4-10. В теле этого цикла содержится другой цикл, который образован блоками 6-8. Его назначение станет ясно из дальнейшего разбора алгоритма. После входа в наружный цикл его счетчик i примет значение 1, что в рамках нашего метода подразумевает первый проход по массиву.
Далее будут выполнены блоки 5-10, составляющие тело наружного цикла. В блоке 5 размещены две вспомогательные переменные V и L. Первая из них предназначена для фиксирования наименьшего элемента, а вторая – для запоминания его индекса. Так как i = 1, то при первом проходе в блоке 5 V примет значение первого элемента, а L значение 1. Затем во внутреннем цикле, образованном блоками 6-8, где его счетчик j будет изменяться от 2 до N, последовательно проводится сравнение соответствующих элементов массива Z со значением переменной V. При этом всякий раз, как будет найден меньший чем v элемент, значение V будет заменено на значение этого элемента, а в переменной L будет зафиксирован его индекс. Понятно, что после выполнения внутреннего цикла в переменной V будет содержаться значение, равное наименьшему элементу, а в L – индекс этого элемента. В блоке 9 далее проверяется, не является ли наименьший элемент первым элементом массива. Если это не так, то в блоке 10 на место наименьшего элемента (его номер L) запишется первый (т. к. при первом проходе L =1 ), а на место первого элемента – наименьший (он равен V). После этого произойдет возврат управления к заголовку наружного цикла блоку 4. В нем значение счетчика станет равным i = 2. Затем вновь выполняется его тело, но уже для нового значения счетчика i. Теперь с помощью блоков 5-10 отыскивается наименьший элемент массива начиная с номера 2. Затем в блоках 9-10 он займет второе место в массиве и т. д. Когда тело наружного цикла выполнится (N-1), раз массив будет отсортирован.
В блоке 12 отсортированный массив будет выведен и в блоке 13 алгоритм окончит работу.
Алгоритмы со структурами вложенных циклов часто используют при решении задач обработки двумерных массивов. В таких алгоритмах счетчики циклов используются для манипуляции с индексами массивов.
Дан двумерный квадратный массив Z, состоящий из N строк и N столбцов. Необходимо найти среднее арифметическое S его отрицательных элементов и заменить положительные элементы побочной диагонали массива средним арифметическим S.
Блок-схема алгоритма
Блок-схема алгоритма показана на рисунке выше. Она состоит из 13 блоков. В блоке 2 переменная N и весь массив Z заполняются константами. В блоке 3 рабочие переменные S и К получает значение нуль. Переменная S сначала будет играть роль сумматора отрицательных элементов массива, затем после накопления суммы она примет значение среднего арифметического. Переменная К нужна для подсчета количества отрицательных элементов массива.
В блоках 4-7 выполняется накопление суммы отрицательных элементов массива.
Эти блоки образует два вложенных цикла, причем внутренний цикл со счетчиком j является телом наружного цикла со счетчиком i. Проанализируем работу этой структуры.
После входа в наружный цикл в блоке 4 переменная i примет значение i = 1. Далее будет выполнено его тело ( блоки 5-7 ), которое, в свою очередь, также является циклом. После входа во внутренний цикл в блоке 5 переменная j примет значение j = 1. Затем в блоке 6 проверяется на отрицательность элемент массива Z, расположенный в первой строке и первом столбце, т. к. i = 1 и j = 1.
Если он окажется отрицательным, то в блоке 7 переменная К увеличится на 1, а к S добавляется значение этого элемента. После этого выполняется возврат к блоку 5, т. е. к заголовку внутреннего цикла. Здесь j увеличится на 1, станет равной j = 2 и управление перейдет к блоку 6. В нем проверяется элемент, стоящий все в той же первой строке, но во втором столбце (i = 1, j = 2). Если он окажется отрицательным, то К снова увеличится на 1, а к накопленному к этому времени S добавляется значение этого элемента и т.д. Когда полностью выполнится внутренний цикл, т. е. переменная j "пробежит" от 1 до N, в переменную S накопится сумма всех отрицательных элементов первой строки массива, а в К – их количество. Теперь управление передается к блоку 4 заголовка наружного цикла, где i станет равной i = 2. Снова будет отработано его тело, т. е. цикл 5-7. При этом будет найдена уже сумма отрицательных элементов первых двух строк массива, а в К сохранится количество этих элементов. Когда выполнится весь наружный цикл, в S будет константа, равная сумме отрицательных элементов всего массива, а в К – их количество. Теперь управление перейдет к блоку 8. Если окажется, что в массиве есть отрицательные элементы (К>0), то в блоке 9 вычисляется среднее арифметическое как отношение суммы элементов к их количеству. Результат помещается а ту же переменную S. Отметим, что если бы блок 8 проверки отсутствовал, то при К = 0 (в массиве нет ни одного отрицательного элемента) в блоке 9 из-за деления на нуль возникла бы ошибка. Эта ошибка повлекла бы аварийное завершение вычислений до окончания работы алгоритма.
Далее выполняется блоки 10-11, которые также образует цикл. В нем производится замена элементов побочной диагонали на среднее арифметическое S (побочной диагональю является прямолинейная цепочка ячеек в диапазоне от нижнего левого угла до верхнего правого угла массива). Обратите внимание, на то что переменная i, которая использовалась ранее, в целях экономии памяти применяется вновь.
Проследим работу этого цикла. После входа в блок 10 счетчик примет значение i = 1. Затем в блоке 11 при этом значении будет вычислен индекс столбца элемента N – 1 + i = N. Таким образом, элемент с индексами (1, N) станет равным S. На втором круге цикла i увеличится на 1 и станет i = 2. Нетрудно видеть, что теперь элемент (2, N-1) станет равным S и т. д. На последнем круге цикла элемент (N, 1) получит значение S, что завершит изменение значений всех элементов побочной диагонали на среднее арифметическое S.
Наконец, в блоке 12 измененный массив будет выведен и в блоке 13 алгоритм закончит работу.
Перестановки элементов в массиве
При перестановках элементы массива меняются местами друг с другом. Хотя их значения в результате перестановок и не изменяются, но изменяется порядок следования элементов в массиве.
Для выполнения перестановок обычно используется третья переменная, которая служит для временного хранения одного из элементов и играет роль буфера обмена.
Например, переставим местами первый и второй элементы массива а, используя для временного хранения переменную buf.
buf:=a[1]; а[1]:=а[2]; a[2]:=buf;
В случае перестановки строк матрицы необходимо переставить местами все элементы двух строк.
Например, при перестановке двух строк, скажем, первой и второй, не обязательно использовать в качестве буфера обмена целый массив. Одной переменной вполне достаточно, т. к. перестановки всех элементов строк выполняются по очереди.
for j:=1 to m do
begin
buf:= a[1,j]; a[1,j]:=a[2,j]; a[2,j]:=buf;
end;
Хорошим примером перестановки элементов двумерного массива является транспонирование матрицы. При транспонировании элементы матрицы переставляются таким образом, что строки исходной матрицы становятся столбцами транспонированной матрицы. При этом элементы, расположенные на главной диагонали исходной и транспонированной матриц, одни и те же. Операция транспонирования сводится к обмену элементов матрицы, расположенных симметрично относительно главной диагонали.
Практическая часть
Пример 1. Двумерный массив целых чисел размером 4*3 заполнен случайным образом. Найдите максимальный элемент, а также укажите номер строки и столбца, содержащие этот элемент.
Для решения этой задачи надо выполнить следующие действия:
сформировать массив и вывести его элементы на экран;
найти максимальный элемент, индекс максимального элемента;
вывести максимальный элемент, номер строки и номер столбца максимально элемента.
Составляем или формализуем условие задачи:
Математическая модель.
a) исходные данные:
возьмем a – массив двумерный, n=4 – число строк, m=3 – число столбцов,
Max – максимальный элемент, Imax – номер строки максимального элемента, Jmax – номер столбца максимального элемента. i, j – соответственно индекс строки и индекс столбца.
Алгоритм.
Сначала считаем, что максимальный элемент – Мax есть а[1,1];
Сравниваем этот элемент со всеми остальными элементами массива, начиная с самого себя в цикле. Зачем необходимо сравнивать элемент сам с собой? Дело в том, что, если далее начинать сравнивать Мax в цикле при i=1 и j=2, то элемент 2 строчки и 1 столбца не будет сравниваться с Мax.
Если первый элемент оказался меньше или равен текущему элементу, то в кандидаты в максимумы будем считать текущий элемент.
Почему меньше или равно? Так как сравниваем с самого себя.
На рисунке ниже представлена блок-схема нахождения максимального элемента.
Программа.
Program Maxsimum;
Uses CRT;
const n=4; m=3;
type
Mass=array[1..n,1..m] of integer;
Var
a:Mass;
I, j, Max, Imax, Jmax: integer;
Begin
Clrscr;
Randomize;
for i:=1 to n do
begin
for j:=1 to m do
begin
a[I,j]:=-50+random(101);
write(a[I,j]:4);
end;
writeln;
end;
Max:=a[1,1];
for i:=1 to n do
for j:=1 to m do
if Max:<=a[i,j] then
begin
Max:=a[i,j];
Imax:=i: Jmax:=j:
end;
Writeln(‘Max=’,Max);
Writeln(‘Imax=’,Imax);
Writeln(‘Jmax=’,Jmax);
Readln;
end.
Пример 2. Выделение элементов массива относительно главной диагонали.
uses crt;
const
row=3; { количество строк }
col=row; { количество столбцов }
var
a: array[1..row,1..col]of integer;
b,c: array[1..row*col]of integer;
i,j,n,m: integer;
begin
clrscr; writeln('Введите массив по строкам');
for i:=l to row do
begin
write('строка № ',i,' ') ;
for j:=l to col do read(a[i,j]);
readln;
end;
n:=0; ( количество элементов на главной диагонали и выше }
m:=0; { количество элементов ниже главной диагонали }
for i:= 1 to row do
for j : = 1 to col do
if j>=i then { элемент стоит на главной диагонали и выше }
begin
n:=n+1; { найден еще один элемент }
b[n]:=а[i,j];{ сохранить в массив b под номером n }
end
else { элемент расположен ниже главной диагонали }
begin
m:=m+1; { найден еще один элемент }
c[m] :=a[i,j];{ сохранить в массив с под номером m }
end;
writeln('Элементы на главной диагонали и выше:');
for i:= 1 to n do write(b[i],' '); writeln;
writeln('Элементы ниже главной диагонали:');
for i:= 1 to m do write(с[i],' '); writeln; readln;
end.
Пример 2. Транспонировать матрицу случайных чисел.
const
row=3; col=row;
var
a: array[1..row,1..col] of integer;
i,],buf: integer;
begin
randomize; {инициализация датчика случайных чисел }
writeln('Исходная матрица случайных чисел:');
for i:= 1 to row do
begin
for j:= 1 to col do
begin
a[i,j]:=random(100);{случайное значение элемента }
write (a[i,j]:4); {вывод элемента массива на экран }
end;
writeln;
end;
{транспонирование матрицы }
for i:=1 to row do {просмотр всех строк матрицы }
{просмотр элементов в строке, расположенных выше главной диагонали }
for j:=i+1 to col do
{ обмен элементов, симметричных относительно главной диагонали }
begin
buf:=a[i,j]; a[i,j]:=a[j,i]; a[j,i]:=buf;
end;
writeln('Результат транспонирования матрицы:');
for i:= 1 to row do
begin
for j:= 1 to col do write(a[i,j]:4);
writeln;
end;
end.
Задания для самостоятельного выполнения
Ознакомиться с теоретическими сведениями по теме «Двумерные массивы».
Составить программу для обработки двумерного массива в соответствии с вариантом задания, указанного в таблице.
Составить блок-схему решения задачи.
Разработать программу в среде Turbo Pascal 7.0.
Составить систему тестов и проверить работу программу на всех возможных значениях исходных данных.
Ответить на контрольные вопросы.
Результаты выполнения лабораторной работы оформить в виде отчета.
Индивидуальные задания:
Вариант 1. В прямоугольной матрице, размерностью n*m, заполненной случайным образом числами из промежутка [-40,30], найти сумму и количество элементов каждого столбца с заданным условием (хранить эти значения в массивах): элементы, кратные k1 или k2.
Вариант 2. В прямоугольной матрице, размерностью n*m, заполненной случайным образом числами из промежутка [-40,30], найти сумму и количество элементов каждого столбца с заданным условием (хранить эти значения в массивах): элементы, попадающие в промежуток от А до В.
Вариант 3. В прямоугольной матрице, размерностью n*m, заполненной случайным образом числами из промежутка [-40,30], найти сумму и количество элементов каждого столбца с заданным условием (хранить эти значения в массивах): данные элементы положительные и лежат выше главной диагонали.
Вариант 4. В прямоугольной матрице, размерностью n*m, заполненной случайным образом числами из промежутка [-40,30], найти сумму и количество элементов каждого столбца с заданным условием (хранить эти значения в массивах): элементы, которые являются простыми числами.
Вариант 5. Найти сумму элементов в строках с k1-й по k2-ю в прямоугольной матрице, размерностью n*m
Вариант 6. Найти номера всех максимальных элементов в прямоугольной матрице, размерностью n*m.
Вариант 7. Найти номера первых отрицательных элементов каждой строки (столбца) в прямоугольной матрице, размерностью n*m.
Вариант 8. Найти номера последних отрицательных элементов каждой строки (столбца) в прямоугольной матрице, размерностью n*m
Вариант 9. Найти количество элементов в каждой строке, больших (меньших) среднего арифметического элементов заданной строки в прямоугольной матрице, размерностью n*m
Вариант 10. Определить является ли прямоугольная матрица размерностью n*m логическим квадратом, то есть суммы по всем горизонталям, вертикалям и двум диагоналям должны быть равны.
Вариант 11. Определить, есть ли в прямоугольной матрице, размерностью n*m строка (столбец), состоящая только из положительных элементов.
Вариант 12. Определить, есть ли в прямоугольной матрице, размерностью n*m строка (столбец), состоящая только из нулевых элементов.
Вариант 13. Определить, есть ли в прямоугольной матрице, размерностью n*m строка (столбец), состоящая только из элементов равных числу А.
Вариант 14. Определить, есть ли в прямоугольной матрице, размерностью n*m строка (столбец), состоящая только из элементов, принадлежащих промежутку от А до В.
Вариант 15. В каждой строке (столбце) прямоугольной матрицы размерностью n*m сменить знак максимального по модулю элемента на противоположный.
Вариант 16. Последний отрицательный элемент каждого столбца в прямоугольной матрице, размерностью n*m заменить нулём.
Вариант 17. В прямоугольной матрице, размерностью n*m положительные элементы умножить на первый элемент соответствующей строки, а отрицательные – на последний, то есть положительные элементы первой строки умножаем на первый элемент первой строки, а отрицательные – на последний элемент также первой строки, то же самое и с остальными строками.
Вариант 18. В прямоугольной матрице, размерностью n*m заменить все элементы строки с номером k и столбца с номером l на противоположные по знаку (элемент стоящий на пересечении, не изменять).
Вариант 19. В прямоугольной матрице, размерностью n*m к элементам столбца k1 прибавить элементы столбца k2.
Вариант 20. Составить программу вывода на экран арифметического квадрата, в нём первый столбец и первая строка заполнены 1, а каждый из остальных элементов равен суме своих соседей сверху и слева.
Вариант 21. Заполнить массив А размером n*m следующим образом, например, для n=5 и m=7:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
Вариант 22. Дан двуменый массив B(NM). Получить одномерный массив A,элементы которого равны количеству отрицательных элементов всоответствующем столбце массива B. Найти минимальный элементмассива B.
Вариант 23. Заполнить массив А размером n*m следующим образом, например, для n=4 и m=7:
1 |
0 |
2 |
0 |
3 |
0 |
4 |
0 |
5 |
0 |
6 |
0 |
7 |
0 |
8 |
0 |
9 |
0 |
10 |
0 |
11 |
0 |
12 |
0 |
13 |
0 |
14 |
0 |
Вариант 24. Определить, является ли данный квадратный массив симметричным относительно своей главной диагонали.{Если массив является симметричным, то для него выполняется равенство a[i,j]=a[j,i] для всех i=l,..., n и j=l,..., n при условии, что i>j. Но если встретится хотя бы одна такая пара, что соответствующие элементы не будут равны, то массив будет несимметричным }
Вариант 25. В прямоугольной матрице, размерностью n*m удалить строку с номером k. {Для того, чтобы удалить строку с номером к, необходимо: - Сдвинуть все строки, начиная с данной, на одну вверх. - Последнюю строку "обнулить", то есть всем элементам последней строки присвоить нулевое значение. Будем выводить на экран сначала все строки, а второй раз, после удаления, на одну меньше.}
Контрольные вопросы
Укажите основные правила организации вложенных циклов.
Как организовать ввод матрицы размером NxM элементов?
Как организовать вывод матрицы в общепринятом виде?
Укажите какие особенности существуют в работе с двумерными массивами по сравнению с одномерными.
Как вывести двумерный массив в виде таблицы?
Можно ли выйти из внутреннего цикла до его окончания?
Как организовать вывод нижней треугольной матрицы в общепринятом виде?
