Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Строки и функции и матрицы.doc
Скачиваний:
2
Добавлен:
15.11.2018
Размер:
264.19 Кб
Скачать

Двумерные массивы

Мы перешли к самому интересному моменту – это двумерные массивы Паскаль! По разновидностям я их привык делить на две категории – это простые и матрицы. Но особый интерес, я питаю к матрицам )). Именно по этим двумерным массивам Паскаль и составлено больше всего задач и ориентируются при составлении  задач преподаватели зачастую именно к ним. Понять их можно спокойно. Потому что теоретического материала по ним достаточно много. И при решении стандартных задач, которые прикреплены к теории – вроде то всё понятно и проще уж некуда, но как только мы сталкиваемся с задачей какого то другого вида – мы сразу теряемся. А происходит это потому что нас обучают стандарту:

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

то есть показали два цикла FOR, а дальше как найти диагональ, или как обменять строки и т.д. – то думай ученик сам. “Напрягай сам мозги” – требуют от нас преподаватели. А сами то не объясняют как надо. Я вам объясню, и всем помогу )))!!! Очень всё просто. Я сидел над задачей Паскаль, в которой требовалось «обменять местами главную и побочную диагонали». Я думал, что это смертельный случай, и такую программу напишет только профессор. Но как не странно – написал на следующий день я её сам! Вот как это было: Матрица (двумерный массив) в Паскаль системе мы представляем как квадрат, где каждый элемент (ячейка) имеет собственные координаты(i,j). Вот я нарисовал этот самый квадрат и стал думать как бы их то обменять. 1,1 1,2 1,3 2,1 2,2 2,3 3,1 3,2 3,3 , где целая часть (i) – это строка, а десятые (j) – это номер столбца Присмотревшись повнимательнее, я заметил закономерность, что при обмене и пропускании его через цикл - индекс строки остаётся неизменным, а поменять осталось только индексы столбцов. Пораскинув ещё немного извилинами – я перенёс всё это в систему Паскаль, и получилась у меня первая программа, алгоритм которой – я сообразил сам. Поняв эту фишку – дальше все программы “пошли у меня как по маслу”!!!

Понятие двумерного массива. Описание типа массива. Формирование значений элементов массива случайным образом

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

Мы уже рассматривали формирование и обработку одномерных массивов. Вспомним, что в массив мы объединяем конечную последовательность компонентов одного типа и даем им общее имя. Каждый отдельный компонент массива называется элементом. Количество элементов называется размером массива. Тип элементов определяет тип массива. Размер и тип массива указываются при его описании, причем размер может быть указан либо конкретным значением, либо ранее определенной константой. Номер элемента называется индексом. Индексы могут быть целыми положительными константами или целыми переменными. Чтобы обратиться к некоторому элементу массива, нужно рядом с идентификатором массива в скобках указать индекс элемента.

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

Размер двумерного массива задается парой чисел: M*N, где M - число строк, а N - число столбцов в таблице.

Пусть задан двумерный массив Matr, имеющий размер 10*20. Этот массив на языке Паскаль может быть описан следующим образом:

Var   Matr : array [1..10,1..20] of integer;

тогда

  Matr[5,7] - элемент, расположенный в 5-ой строке и в 7-ом столбце.

Любая константа, переменная, значение функции или выражения в Турбо Паскале характеризуется своим типом. Тип любого из этих объектов определяет множество допустимых значений, которые может иметь объект, а также множество допустимых операций, которые применимы к объекту. Кроме того, тип определяет и формат внутреннего представления значения объекта.

Имя, которое программист присваивает своему определяемому типу, - произвольный идентификатор. Объявление типа должно быть сделано в разделе объявлений, и ему должно предшествовать кодовое слово Type.

Отличительной особенностью массивов является то обстоятельство, что все их компоненты суть данные одного типа (возможно, структурированного); эти компоненты можно легко упорядочить и обеспечить доступ к любому из них простым указанием его порядкового номера, например:

Type   Digit = array [0..9] of integer;   Matrix = array [1..100, 0..9] of real; Var   m : Matrix;   d : Digit;   i : integer;

Описание типа массива задается следующим образом:

  <имя типа> = array [<сп. инд. типов>] of <тип>;

где:

<имя типа> - правильный идентификатор, <сп. инд. типов> - список из одного или нескольких индексных типов, разделенных запятыми, <тип> - любой тип Турбо Паскаля.

Примечание. Обычно в качестве индексного типа используется тип-диапазон, в котором задаются границы изменения индексов через две точки (..). Так как <тип>, идущий за кодовым словом of, - любой тип Турбо Паскаля, он может быть, в частности, другим массивом.

Рассмотрим примеры.

Пример 1. Массив можно описать как одномерный, элементами которого в свою очередь являются одномерные массивы.

Const   n=2; m=3; Type   MyArray1 = array [1..m] of integer;   MyArray2 = array [1..n] of MyArray1; Var   V : MyArray1;   A : MyArray2;

В данном случае переменная V объявлена как одномерный массив из трех элементов целого типа, а переменная А описана как двумерный массив из двух строк, в каждую из которых включено по три элемента.

Пример 2. Описание массива можно сократить, исключив определение массива MyArray1.

Const   n=2; m=3; Type   MyArray2 = array [1..n] of array [1..m] of integer; Var   A : MyArray2;

Пример 3. Еще более краткое описание массива А можно получить, указывая имя массива и диапазоны изменения индексов для каждой размерности массива (чем мы уже пользовались).

Const   n=2; m=3; Type   MyArray2 = array [1..n, 1..m] of integer; Var   A : MyArray2;

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

Const   n=2; m=3; Var   A : array [1..n, 1..m] of integer;

Формирование значений элементов массива случайным образом и с клавиатуры и вывод их на экран

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

Очень часто значения элементов массива вводятся с клавиатуры. Этот способ задания информации слишком трудоемок при работе с массивами больших размеров. Для отладки широкого класса алгоритмов такой ввод информации должен быть заменен формированием элементов массива случайным образом. Для этого используют встроенные средства Турбо Паскаля: процедуру Randomize и функцию Random. Вы уже сталкивались с этими средствами. Сегодня же наша задача создать процедуру ввода элементов в массив и процедуру вывода элементов на экран.

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

Procedure InsertMas1(Var X : MyArray; n, m: integer); Var   i, j : integer; Begin   Randomize;   for i := 1 to n do {пробегая последовательно строки массива}     for j := 1 to m do {просмотрим каждую ее ячейку текущего столбца}       X[i, j]:= Random(50); {и запишем туда случайное число, которое сформирует компьютер в диапазоне [0..49]} End;

Теперь, чтобы воспользоваться этой процедурой, достаточно вызвать ее в основном разделе программы, передав ей параметры.

Рассмотрим процедуру вывода элементов массива на экран. Для того, чтобы вывести наш массив на экран в виде таблицы, поставим при переходе к новой строке  оператор writeln и применим формат вывода элементов (:5).

Procedure PrintMas(X : MyArray; n, m: integer); Var   i, j : integer; Begin   for i := 1 to n do {пробегая последовательно строки и столбцы массива}     begin       for j := 1 to m do         write(X[i, j]:5); {выведем элемент массива на экран, выделив ему 5 знакомест}       writeln; {переход на новую строку}     end; End;

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

Рассмотрите процедуру, решающую следующую задачу.

Задача. Дана таблица действительных чисел. Сосчитайте сумму всех чисел в таблице.

Procedure Summa(A : MyArray; n, m: integer; Var S: real); Var   i, j : integer; Begin   S:= 0;   for i := 1 to n do     for j := 1 to m do       S := S+A[i,j]; End.

Обратите внимание, что внутри цикла со счетчиком i организован цикл со счетчиком j. В результате суммируются в начале числа 1-й строки (i=1, при j=1, 2, ..., m), затем суммируются числа 2-й строки (i=2, при j=1, 2, ..., m) и т.д.

В данной программе в теле одного цикла содержится другой цикл. Такие циклы, как Вы уже знаете, называются вложенными. Причем цикл со счетчиком i является внешним, а цикл со счетчиком j - внутренним. Не забывайте основное правило при написании вложенных циклов: последний оператор внутреннего цикла должен либо предшествовать, либо совпадать с последним оператором внешнего цикла. Вложенные циклы напоминают матрешек, вложенных одна в другую.

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

Задание. Ниже приведен фрагмент решения некоторой задачи. Внимательно рассмотрев решение, сформулируйте решаемую задачу и оформите по всем правилам, применив знания текущего занятия.

. . .   for i := 1 to N do     Begin       M := a[i,1];       S := a[i, 1];       for j := 2 to N do         begin           if M>a[i, j]             Then               M := a[i, j];           S := S+a[i, j];         end;       writeln (i:7, M:6, S:6:3);     End; . . .

Двумерные массивы

Описание

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

Рассмотрим матрицу А размерностью 2*3, то есть в ней будет две строки, а в каждой строке по три элемента:

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

Существуют несколько способов объявления двумерного массива.

Способ 1. В Паскале двумерный массив можно описать как одномерный, элементами которого являются одномерные массивы. Например, для матрицы А, приведённой выше:

Const n = 2; m = 3; Type omyarray = Array[1..m] Of <тип элементов >; dmyarray = Array[1..n] Of omyarray; Var v : omyarray; a : dmyarray;

В данном случае переменная v объявлена как одномерный массив из трёх элементов вещественного типа. Переменная а описана как двумерный массив из двух строк, каждую из которых включено по три элемента.

Способ 2. Описание массива А можно сократить, исключив определение типа omyarray в определении типа dmyarray:

Const n = 2; m = 3; Type dmyarray = Array[1..n, 1..m] Of <тип элементов>; Var a : dmyarray.

Способ 3. Ещё более краткое описание массива А можно получить, указывая имя массива и диапазоны изменения индексов для каждой размерности массива:

Const n = 2; m = 3; Type dmyarray = Array[1..n, 1..m] Of <тип элементов >;

Var a : dmyarray.

Если указанный тип используется для определения одного массива в программе, то удобно объявление массива в разделе описания переменных:

Var a: Array [1..n, 1..m] Of < тип элементов >.

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

Пример 1

В приведённом ниже примере осуществляется ввод и вывод двумерного массива А размерностью 10*15. Формирование и вывод массива описаны в виде двух процедур, которые вызываются последовательно из основной программы. Надо заметить, что формирование двумерного массива можно осуществлять всеми тремя способами, описанными для одномерных массивов, то есть: ввод с клавиатуры, через генератор случайных чисел или с помощью файла. Пусть в нашем примере элементы задаются генератором случайных чисел.

Program Example_45; Const n = 2; m = 15; Type dmyarray = Array[1..n., 1..m] Of Integer; Var A : dmyarray;

Procedure Init(Var x: dmyarray); {процедура формирования массива} Var i, j : Integer; Begin For i:=1 To n Do For j:=1 To m Do x[i,j]:=-25+Random(51); End;

Procedure Print(x: dmyarray); {процедура вывода массива на экран} Var i, j : Integer; Begin For i:=1 To n Do Begin {ввод i-ой строки массива} For j:=1 To n Do Write(x[i,j]:5); Writeln; {переход на начало следующей строки} End;

Begin{основная программа} Init(A); {вызов процедуры формирования массива} Writeln('Массив А:'); Print(A); {вызов процедуры вывода} Readln; End.

При решении задач с двумерными массивами можно выделить несколько видов задач.