Алгоритмы обработки массивов Лекция 8 Масюк В. М.
Алгоритмы обработки массивов Лекция 8 Масюк В. М.
Объявление массива Массив — это составной тип данных, состоящий из фиксированного числа элементов одного и того же типа. Для описания массива предназначено словосочетание array of. После слова array в квадратных скобках записываются границы массива, а после слова of — тип элементов массива, например: type TStates = array[1. . 50] of string; TCoordinates = array[1. . 3] of Integer;
После описания типа можно переходить к определению переменных и типизированных констант: var States: TStates; { 50 strings } const Coordinates: TCoordinates = (10, 20, 5); { 3 integers } Обратите внимание, что инициализация элементов массива происходит в круглых скобках через запятую.
Объявленные выше массивы являются одномерными, так как имеют только один индекс. Если при описании массива задано два индекса, массив называется двумерным, если n индексов — n-мерным. Двумерные массивы используются для представления таблицы. Вот пример объявления таблицы, состоящей из 5 колонок и 20 строк: var Table: array[1. . 5] of array[1. . 20] of Double; То же самое можно записать в более компактном виде: var Table: array[1. . 5, 1. . 20] of Double; Чтобы получить доступ к отдельному элементу многомерного массива, нужно указать значение каждого индекса, например Table[2][10] или в более компактной записи Table[2, 10]
Работа с массивами Массивы в целом участвуют только в операциях присваивания. При этом все элементы одного массива копируются в другой. Например, если объявлены два массива A и B, var A, B: array[1. . 10] of Integer; то допустим следующий оператор: A : = B; Оба массива-операнда в левой и правой части оператора присваивания должны быть не просто идентичны по структуре, а описаны с одним и тем же типом!
Type Massiv = Array[1. . 10] Of Real; Var A, B : Massiv; C, D : Array[1. . 10] Of Real; E : Array[1. . 10] Of Real; типы переменных A, B эквивалентны, и поэтому данные переменные совместимы по присваиванию; тип переменных C, D также один и тот же, и поэтому данные переменные также совместны по присваиванию. Но тип переменных C, D не эквивалентен типам переменных A, B, E, поэтому, например, A и D не совместны по присваиванию.
program Console; {$APPTYPE CONSOLE} uses Sys. Utils; var A: array[1. . 5] of Double; Sum: Double; I: Integer; begin for I : = 1 to 5 do Readln(A[I]); Sum : = 0; for I : = 1 to 5 do Sum : = Sum + A[I]; Writeln(Sum); Writeln('Press Enter to exit. . . '); Readln; end. Пример
Для массивов определены две встроенные функции — Low и High. Они получают в качестве своего аргумента имя массива. Функция Low возвращает нижнюю, а High — верхнюю границу этого массива. Функции Low и High чаще всего используются для указания начального и конечного значений в операторе цикла for. Поэтому вычисление суммы элементов массива A лучше переписать так: for I : = Low(A) to High(A) do Sum : = Sum + A[I];
В операциях с многомерными массивами циклы for вкладываются друг в друга. Например, для инициализации элементов таблицы, объявленной как var Table: array[1. . 5, 1. . 20] of Double; требуются два вложенных цикла for и две целые переменные Col и Row для параметров этих циклов: for Col : = 1 to 5 do for Row : = 1 to 20 do Table[Col, Row] : = 0;
Массивы, как и другие типы данных, могут выступать в качестве параметров процедур и функций. Пример - функция, вычисляющая среднее значение в массиве действительных чисел: const Max = 63; type TStatistics = array [0. . Max] of Double; function Average(const A: TStatistics): Double; var I: Integer; begin Result : = 0; for I : = Low(A) to High(A) do Result : = Result + A[I]; Result : = Result / (High(A) - Low(A) + 1); end;
Требование фиксированного размера для массива-параметра часто является чрезмерно сдерживающим фактором. Процедура для нахождения среднего значения должна быть способна работать с массивами произвольной длины. Для этой цели в язык Delphi введены открытые массивы-параметры. Такие массивы были заимствованы разработчиками языка Delphi из языка Modula-2 function Average(const A: array of Double): Double; var I: Integer; begin Result : = 0; For I : = Low(A) to High(A) do Result : = Result + A[I]; Result : = Result / (High(A) - Low(A) + 1); end;
Существует только два способа использования открытых массивов: обращение к элементам массива и передача массива другой подпрограмме, принимающей открытый массив. Нельзя присваивать один открытый массив другому, потому что их размеры заранее неизвестны. Вот пример использования функции Average: var Statistics: array[1. . 10] of Double; Mean: Double; begin . . . Mean : = Average(Statistics); Mean : = Average([0, Random, 1]); . . . end; Конструктор открытого массива представляет собой заключенный в квадратные скобки список выражений. В выражениях могут использоваться константы, переменные и функции. Тип выражений должен быть совместим с типом элементов массива.
Уплотнение структурных данных в памяти С целью экономии памяти, занимаемой массивами и другими структурными данными, вы можете предварять описание типа зарезервированным словом packed, например: var A: packed array[1. . 10] of Byte; Ключевое слово packed указывает компилятору, что элементы структурного типа должны храниться плотно прижатыми друг к другу, даже если это замедляет к ним доступ. Если структурный тип данных описан без ключевого слова packed, компилятор выравнивает его элементы на 2 - и 4 -байтовых границах, чтобы ускорить к ним доступ. Заметим, что ключевое слово packed применимо к любому структурному типу данных, т. е. массиву, множеству, записи, файлу, классу, ссылке на класс.
Реализация в виде процедуры: Type TA=array[1. . 110, 1. . 100] of integer; Var MA: TA; Procedure Gen_Rand(var A: TA; N, M: byte); Var i 1, i 2: byte; Begin Randomize; //запуск генератора случайных чисел For i 1: =1 to M do For i 2: =1 to N do A[i 1, i 2]: =random(100); //установить значение End; Генерация двумерного массива
начало А, N, M I 1=1, M I 2=1, N A[I 1, I 2]: =random(100) А конец Пример блок-схемы
Program proizvedenie; Type Matrix=array [1. . 10, 1. . 10] of integer; Var A: matrix; N, m, i, j: byte; P: integer; Procedure vvod (var m: matrix); Var k , h : byte ; Begin For i : =1 to n do For j : =1 to m do M[i, j]: = random(10); End; Procedure print (m: matrix); Var k, h: byte; Begin For i: =1 to n do begin For j: =1 to m do Write (M[i, j]: 4); Writeln; end ; End ; Begin {начало основной программы} Writeln (‘Введите размерность матрицы: ’); Readln(N, M); Vvod(a); Print(a); P: =1; For i: =1 to N do For j: =1 to M do If a[i, j]<>0 then p: =p*a[i, j]; Writeln ( p ); End.
Над элементами массивами чаще всего выполняются такие действия, как а) поиск значений; б) сортировка элементов в порядке возрастания или убывания; в) подсчет элементов в массиве, удовлетворяющих заданному условию. Пример: дан линейный массив целых чисел. Подсчитать, сколько в нем различных чисел.
{Подсчет количества различных чисел в линейном массиве. Идея решения: используем вспомогательный массив, элементами которого являются логические величины ( False - если элемент уже встречался ранее, True - иначе)} Program Razlichnye_Elementy; Var I, N, K, Kol : Integer; A : Array [1. . 50] Of Integer; Lo : Array [1. . 50] Of Boolean; Begin Write('Введите количество элементов массива: '); Read. Ln(N); FOR I : = 1 TO N DO Begin Write('A[', I, ']='); Read. Ln (A[I]); Lo[I] : = True; {Заполняем вспомогательный массив True} End; Kol : = 0; {в которой будет количество разных чисел} FOR I : = 1 TO N DO IF Lo[I] THEN Begin Kol : = Kol + 1; FOR K : = I TO N DO {Во вспомогательный массив заносим значение False, если число уже встречалось ранее или совпадает с текущим элементом A[I]} Lo[K] : = (A[K] <> A[I]) And Lo[K]; End; Write. Ln('Количество различных чисел: ', Kol) END.
Program Obmen; FOR I : = 1 TO N DO Begin Var N, I, J, Max, Ind, Vsp : Max : = A[I, 1]; Ind : = 1; Integer; FOR J : = 2 TO N DO IF A[I, J] > Max THEN A : Array [1. . 15, 1. . 15] Of Begin Integer; Max : = A[I, J]; Begin Ind : = J End; WRITE('Введите количество Vsp : = A[I, I]; элементов в массиве: '); A[I, I] : = A[I, Ind]; READLN(N); A[I, Ind] : = Vsp FOR I : = 1 TO N DO End; FOR I : = 1 TO N DO FOR J : = 1 TO N DO Begin Write. Ln; WRITE('A[', I, ', ', J, '] '); FOR J : = 1 TO N Do Write(A[I, J] : 3); End; READLN(A[I, J]) Write. Ln End; End. Дана целочисленная квадратная матрица. Найти в каждой строке наибольший элемент и поменять его местами с элементом главной диагонали.
Контрольные вопросы и задания Что такое массив? Почему массив является структурированным типом данных? Что такое размерность массива? Существуют ли ограничения на размерность массива? Какого типа могут быть элементы массива? Какого типа могут быть индексы элементов массива? Какие простые типы данных относятся к порядковым? Какими способами может быть заполнен массив? Приведите примеры. Как определить минимальный объём памяти, отводимой под массив? Какие действия выполняют обычно над элементами массива? Может ли массив быть элементом массива?
В каком случае массивы совместны по присваиванию? Пусть элементами массива A (a[1], a[2], a[3], a[4]) являются соответственно x, -x, x 2, -x 2. Чему будет равно значение выражения a[-a[a[3]-2]]+a[-a[a[3]]] при x=2? Можно ли выполнять обход двумерного массива, организовав внешний цикл по столбцам, а внутренний — по строкам? Целесообразно ли использовать ли вложенные циклы, если совершается обход только главной диагонали квадратной матрицы? одной строки матрицы? одного столбца матрицы?
Точно и однозначно сформулировать условие задачи, решение которой приведено в данной программе: Program Kr_N_4; Const NMax = 50; Type Mass = Array[1. . NMax, 0. . NMax-1] Of Real; Var A : Mass; I, J, N : 0. . NMax; C : Real; Begin Write('Количество элементов массива N=? '); Read. Ln(N); For I : = 1 To N Do For J : = 0 To N-1 Do Begin Write('A[', I, ', ', J, ']= '); Readln(A[I, J]) End; For I : = 1 To N Do For J : = 0 To N-1 Do Begin C : = A[I, J]; A[I, J] : = A[N-I+1, J]; A[N-I+1, J] : = C End; For I : = 1 To N Do Begin For J : = 0 To N-1 Do Write(A[I, J]: 5: 2, ' '); Write. Ln End.
Лекция 8 Массивы.ppt
- Количество слайдов: 22

