Работа с двумерными числовыми массивами

Содержание
Введение
1. Теоретическая часть
1.1 Общее понятие о массивах
1.1.1 Определение и область применения
1.1.2 Специфические типы массивов
1.1.3 Реализация массивов
1.1.4 Достоинства массивов
1.1.5 Недостатки массивов
1.2 Массивы в Object Pascal
1.2.1 Статические массивы
1.2.2 Динамические массивы
1.2.3 Функции для работы с массивами
1.3 Использование массивов в рамках проекта
2. Практическая часть
2.1 Постановка задачи
2.2 Функциональная структура приложения
2.3 Описание модулей
2.3.1 Модуль MatrixOperations
2.3.2 Модуль fileIO
2.4 Модуль form
3. Эксплуатационная документация
3.1 Описание применения
3.2 Руководство оператора
Выводы
Приложения

Введение
Ввычислительной технике данные обычно отличают от программ. Программа являетсянабором инструкций, которые детализируют вычисление или задачу, производимуюкомпьютером. Данными же традиционно называется всё, что не выступает в ролипрограммы. В языках высокого уровня данные воплощаются в виде переменных.
Часто передпрограммистами встают задачи, связанные с обработкой стразу множества значенийданных. В таких случаях крайне неудобно для хранения каждого значения заводитьотдельную именованную переменную. Для такой ситуации синтаксис многих языковпредусматривает создание массивов – множеств переменных, доступ ккоторым осуществляется посредством одного имени (имени массива) и одного илинескольких индексов.
Даннаякурсовая работа рассматривает методики использования многомерных массивов всреде Delphi. Она демонстрирует использованиевстроенных возможностей языка, а так же применение широко известных операцийнад массивами, таких как последовательный обход значений, сортировка,циклический сдвиг.

1. Теоретическая часть
 
1.1 Общее понятие о массивах
 
1.1.1 Определение и областьприменения
Массив (или индексный массив), этоименованный набор однотипных переменных, расположенных в памяти непосредственнодруг за другом, доступ к которым осуществляется по индексу. Количествоиспользуемых индексов массива может быть различным. Массивы с одним индексомназывают одномерными, с двумя — двумерными и т. д. Одномерный массив нестрогосоответствует вектору в математике, двумерный — матрице. Массивы хорошоподходят для отображения таких объектов реального мира, как строки (массивысимволов), наборы координат, таблицы данных, математические множества и вообщемножества однотипных объектов.
Без использованиямассивов не обойтись в таких областях программирования как работа с базамиданных, компьютерная графика, визуализация результатов научных экспериментов, статистическийанализ. Массивы являются входными и выходными параметрами процедур сортировки.
Поддержкаиндексных массивов (свой синтаксис объявления, функции для работы с элементамии т. д.) есть в большинстве высокоуровневых языков программирования.Максимально допустимая размерность массива, типы и диапазоны значений индексов,ограничения на типы элементов определяются языком программирования и/иликонкретным транслятором.
В языкахпрограммирования, допускающих объявления программистом собственных типов, какправило, существует возможность создания типа «массив». В определении такоготипа может указываться размер, тип элемента, диапазон значений и типы индексов.В дальнейшем возможно определение переменных созданного типа. Все такиепеременные-массивы имеют одну структуру. Некоторые языки поддерживают дляпеременных-массивов операции присваивания (когда одной операцией всем элементаммассива присваиваются значения соответствующих элементов другого массива).
1.1.2 Специфические типы массивов
Динамическим называется массив, размер которогоможет меняться во время исполнения программы. Для изменения размерадинамического массива язык программирования, поддерживающий такие массивы,должен предоставлять встроенную функцию или оператор. Динамические массивы даютвозможность более гибкой работы с данными, так как позволяют не прогнозироватьхранимые объёмы данных, а регулировать размер массива в соответствии с реальнонеобходимыми объёмами. Обычные, не динамические массивы называют ещё статическими.
Гетерогенным называется массив, в разные элементыкоторого могут быть непосредственно записаны значения, относящиеся к различнымтипам данных. Массив, хранящий указатели на значения различных типов, неявляется гетерогенным, так как собственно хранящиеся в массиве данные относятсяк единственному типу — типу «указатель». Гетерогенные массивы удобны как универсальнаяструктура для хранения наборов данных произвольных типов. Отсутствие ихподдержки в языке программирования приводит к необходимости реализации болеесложных схем хранения данных. С другой стороны, реализация гетерогенноститребует усложнения механизма поддержки массивов в трансляторе языка.
Многомерные массивы, как правило, реализованныекак одномерные массивы, каждый элемент которых является ссылкой на другойодномерный массив.
1.1.3 Реализация массивов
Стандартнымспособом реализации статических массивов с одним типом элементов являетсяследующий:
Под массиввыделяется непрерывный блок памяти объёмом
S*m1*m2*m3…mn,
где S —размер одного элемента, а m1…mn — размеры диапазоновиндексов (то есть количество значений, которые может принимать соответствующийиндекс).
Приобращении к элементу массива A[i1, i2, i3, … in]адрес соответствующего элемента вычисляется как
B+S*(i1p*m1+i2p*m2+…+i(n-1)p*mn-1+inp),
где B — база(адрес начала блока памяти массива), ikp-значение k-го индекса,приведённое к целому с нулевым начальным смещением.
Такимобразом, адрес элемента с заданным набором индексов вычисляется так, что времядоступа ко всем элементам массива одинаково. Первый элемент массива, взависимости от языка программирования, может иметь различный индекс. Различаюттри основных разновидности массивов: с отсчетом от нуля (zero-based), сотсчетом от единицы (one-based) и с отсчетом от специфического значениязаданного программистом (n-based).
Отсчетиндекса элемента массивов с нуля более характерен для низкоуровневых языковпрограммирования, однако этот метод был популяризирован в языках более высокогоуровня языком программирования С.
Болеесложные типы массивов — динамические и гетерогенные — реализуются сложнее.
 
1.1.4 Достоинства массивов
·         Быстрый доступ кэлементам, причём время доступа не зависит от длины массива
·         Элементырасположены в памяти непосредственно друг за другом, что облегчает копированиеи перемещение всего массива целиком
·         Отсутствиенеобходимости в дополнительной памяти
1.1.5 Недостатки массивов
·         для статическогомассива — отсутствие динамики, невозможность удаления или добавления элементабез сдвига других
·         для динамическогои/или гетерогенного массива — более низкое (по сравнению со статическим)быстродействие и дополнительные накладные расходы на поддержку динамическихсвойств и/или гетерогенности.
·         при работе смассивом в отсутствие дополнительных средств контроля — угроза выхода заграницы массива и повреждения «чужих» данных
1.2 Массивы в Object Pascal
Ключевоеслово Array используется для определенияодномерных и многомерные массивов данных. В Object Pascal существует два типа массивов
1.2.1 Статические массивы
Создаются сзаранее определёнными, неизменяемыми размерами. Могут быть одномерными, илимногомерными – во втором случае представляя из себя массив массивов (массивовмассивов и так далее).
Величинакаждой размерности определяется двумя способами, которые могут свободносочетаться при определении многомерного массива:
·         Тип Index, где Index – целый тип, обычно Byte или Word.Диапазон типа определяет диапазон размерности, например 0..255 для Byte
·         Ordinal..Ordinal. Таким образом, можно непосредственно задать диапазонразмерности, например 12..44.
·         Например:
1    var
2    wordArray: Array[Word] of Integer; // размерравенHigh(Word)
3    multiArray: Array[Byte, 1..5] of char; //двумерныймассив
4    rangeArray: Array[5..20] of string; // размерравен16
1.2.2 Динамические массивы
У длядинамических массивов память заранее не выделяется, создаётся только указатель.У таких массивов необходимо задавать размер перед использованием. Например
SetLength(dynArray, 5);
устанавливаетдлину первой размерности массива dynArray в пять, при этом выделяется необходимая память. Для всех динамическихмассивов минимальный индекс равен нулю.
Отдельныеподмассивы многомерного динамического массива могут иметь разные размеры, таккак по сути они являются отдельными массивами.
Примеропределения динамических массивов:
1         var
2         byteArray: Array of Byte; // одномерныймассив
3         multiArray: Array of Array of string; //двумерныймассив
1.2.3 Функции для работы с массивами
Copy(Source: array; StartIndex, Count: Integer ): array – создает копию части массива.
High(type or variable): Ordinal type — возвращает верхнюю границу диапазона значений массива.
Length (const SourceArray: array): Integer- возвращает число элементов в массиве.
Low(type or variable): Ordinal type — возвращает нижнюю границудиапазона значений массива
SetLength (var ArrayToChange: Array type; Dim1Length: Integer {;Dim2Length:Integer; …}) — изменяет размер динамического массива. Для многомерных массивов может приниматьболее одного параметра длины.
Slice (SourceArray: array; Count: Integer):array — создает часть массива для передачи его как параметр в процедуру илифункцию.
Прииспользовании динамических массивов необходимо помнить, что вызовы SetLength выделяют для массива дополнительнуюпамять, которую необходимо освобождать после окончания работы с массивом. Дляэтого ему нужно присвоить специальное значение nil.
 
1.3 Использование массивов в рамкахданного проекта
Работа состатическими массивами более проста и менее затратна в плане использованияресурсов компьютера, но так как в задании нигде не оговариваются конкретныеразмеры исходных матриц, то было принято решение построить программу ну основеиспользования динамических массивов.
Приложение построенотаким образом, что размер используемой матрицы можно менять во времявыполнения, так же он автоматически определяется при загрузке исходных данныхиз файла. Размеры динамических массивов внутри программы изменяютсясоответствующим образом автоматически.
 

2. Практическая часть
 
2.1 Постановка задачи
 
Приложениепредназначено для выполнения специфической обработки матриц. Исходные матрицыдолжны загружаться из файла, либо вводиться непосредственно в элементыинтерфейса приложения.
Граничныеусловия на вводимые данные таковы:
·         Размеры матрицыдолжны лежать в пределах [1; 2147483647]. Если введено число, выходящее изэтого диапазона, либо значение, не являющееся целым числом, то размерустанавливается равным единице.
·         Элементы матрицыдолжны лежать в пределах [-2147483648; 2147483647]. Если какой-то из элементовлежит вне этого диапазона, либо введёно значение, не являющееся целым числом,то элемент устанавливается равным нулю.
·         В заданиях,связанных с подсчётом сумм элементов, результат может лежать в пределах[-9223372036854775808; 9223372036854775807]. Если сумма выходит за эти пределы,результат не определён.
2.2 Функциональная структурапрограммы
Программаразделена на три модуля:
MatrixOperations – различные операции с матрицей
fileIO – сохранение матрицы в файл/ чтениематрицы из файла
form – форма приложения, процедуры обменаданными между массивами и элементами формы. Структура связей модулей такова:

/>
2.3 Описание модулей
 
2.3.1 Модуль MatrixOperations
Это основноймодуль программы, содержащий процедуры для выполнения матричных операций,предусмотренных заданием.
Определяетповсеместно используемые типы «матрица» и «вектор»:
1           type
2           TVector = array of integer;
3           TMatrix = array of TVector;
 
Поискмаксимальных элементов в матрице.
Процедура GetMaxVals,которая, перебирая все строки матрицы, находит в каждой максимальный элемент,записывает его значение в массив maxVal, а его номер столбца в массивmaxValCol. Предварительно процедура выделяет необходимую намять для этихмассивов. Листинг:
1 {
2           формируетмассив максимальных элементов maxValи массив номеров столбцов,
3           содержащихмаксимальные элементы maxValColна основе матрицы arr
4           }
5           procedure GetMaxVals(var maxVal,maxValCol: TVector; const arr: TMatrix);
6           var
7           RowN, ColN, maxInRow: integer;
8           begin
9           //выделимнеобходимый для каждого массива объём памяти
10         SetLength(maxVal, high(arr)+1);
11         SetLength(maxValCol, high(arr)+1);
12         for RowN:= low(arr) to high(arr) do
13         begin//для каждой строки
14         maxVal[RowN]:=low(integer);//поумолчанию максимальное значение -2147483648
15         maxValCol[RowN]:=-1;//по умолчанию номер столбца с макс элементом -1
16         for ColN:= low(arr[RowN]) tohigh(arr[RowN]) do
17         begin//для каждого столбца
18         if arr[RowN, ColN] > maxVal[RowN]then
19         begin//если элемент большемакс значения, то
20         maxVal[RowN]:=arr[RowN,ColN];//максимальное значениеприравняем элементу
21         maxValCol[RowN]:=ColN;//номер столбца приравняемтекущему столбцу
22         end;
23         end;
24         end;
25         end;

Суммыэлементов между диагоналями
Далее идутфункции, осуществляющие подсчёт сумм элементов выше и ниже пересечениядиагоналей, а так же смену местами этих элементов. Главной диагональю считаетсямножество элементов матрицы, индексы которых совпадают, побочной диагональюсчитается та, которая идёт по диагонали из нижнего левого угла матрицы.
Функции GetSumAbove и GetSumBelow проходят соответствующие половиныстрок матрицы, для каждой строки высчитывая диапазон столбцов, из которых нужносуммировать элементы:
1         {возвращаетсумму элементов выше пересечения диагоналей матрицы arr}
2         function GetSumAbove (const arr:TMatrix): Int64;
3         var
4         RowN, ColN: integer;
5         lastColumn: integer;//номерстолбца, содержащего элемент дальней диагонали минус 1
6         begin
7         Result:= 0;
8         for RowN:= 0 to (high(arr) div 2) do
9         begin//с нулевой, по средююстроку
10       lastColumn:= high(arr)-RowN-1;//определимномер столбца последнего элемента, подлежащего суммированию
11       //есличисло столбцов меньше числа строк, то последний столбец может оказаться ближе
12       if lastColumn > high(arr[RowN]) thenlastColumn:= high(arr[RowN]);
13       for ColN:= RowN+1 to lastColumn do //просуммируемэлементыв высчитаныхпределах
14       Result:= Result + arr[RowN, ColN];
15       end;
16       end;
17       {возвращаетсумму элементов ниже пересечения диагоналей матрицы arr}
18       function GetSumBelow(const arr:TMatrix): Int64;
19       var
20       RowN, ColN: integer;
21       lastColumn: integer;//номерстолбца, содержащего элемент дальней диагонали минус 1
22       begin
23       Result:= 0;
24       for RowN:= (high(arr) div 2)+1 tohigh(arr) do
25       begin//со средней попоследнюю строку
26       lastColumn:= RowN-1;//определимномер столбца последнего элемента, подлежащего суммированию
27       //есличисло столбцов меньше числа строк, то последний столбец может оказаться ближе
28       if lastColumn > high(arr[RowN]) thenlastColumn:= high(arr[RowN]);
29       for ColN:= high(arr)-RowN+1 tolastColumn do //просуммируем элементы в высчитаных пределах
30       Result:= Result + arr[RowN, ColN];
31       end;
32       end;
Процедура SwapAboveBelowтаким же образом, как функция GetSumAbove, определяет, какие элементы лежат выше пересечениядиагоналей, но не суммирует их, а каждый меняет местами с элементом того жестолбца, симметричным текущему относительно верхней и нижней границ матрицы.Для смены используется вспомогательная процедура swap для целых чисел, определённая в этомже модуле:
1    {вспомогательнаяпроцедура: поменять местами два целых числа}
2    procedure swap(var first, second:integer);
3    var tmp: integer;
4    begin
5    tmp:= first;
6    first:= second;
7    second:= tmp;
8    end;
9    {поменятьместами элементы выше и ниже пересечения диагоналей матрицы arr}
10  procedure SwapAboveBelow (var arr:TMatrix);
11  var
12  RowN, ColN: integer;
13  lastColumn: integer;//номерстолбца, содержащего элемент дальней диагонали минус 1
14  begin
15  for RowN:= 0 to (high(arr) div 2) do
16  begin//с нулевой, по средююстроку
17  lastColumn:= high(arr)-RowN-1;//определимномер столбца последнего элемента, подлежащего суммированию
18  //есличисло столбцов меньше числа строк, то последний столбец может оказаться ближе
19  if lastColumn > high(arr[RowN]) thenlastColumn:= high(arr[RowN]);
20  forColN:= RowN+1to lastColumndo//для каждого элемента в высчитаныхпределах
21  //поменяемего местами с элементом того же столбца, отстаящем на то же число строк, но отнижней границы матрицы
22  swap(arr[RowN, ColN], arr[high(arr) — RowN, ColN]);
23  end;
24  end;
 
Циклическийсдвиг строк
Далеефункция CircuarShift, осуществляющая циклический сдвиг строк матрицывверх, или вниз. Направление сдвига определяется булевым параметром shiftUp,передаваемым процедуре:
1  {
2  осуществляетциклический сдвиг строк матрицы arrвверх при shiftUp = true,
3  и вниз, при shiftUp = false
4  }
5  procedure CircuarShift(var arr: TMatrix;shiftUp: boolean);
6  var
7  RowN: integer;
8  tmpRow: TVector;//временнаяпеременная для хранения строки иатрицы
9  
10           begin
11           
12           ifhigh(arr)
13           if shiftUp then
14           begin//если сдвиг вверх
15           tmpRow:= arr[high(arr)];//сохранимпоследнюю строку матрицы
16           arr[high(arr)]:= arr[0];//приравняемпоследнюю строку первой
17           for rowN:= 0 to high(arr)-2 do
18           begin//для строк с нулевойпо пред-предпоследнюю
19           arr[rowN]:=arr[rowN+1];//текущаястрока равна нижней
20           end;
21           arr[high(arr)-1]:=tmpRow;//предпоследнюю строкуприравняем последней
22           end
23           else
24           begin//иначе, если сдвиг вниз
25           tmpRow:= arr[0];//сохраним нулвую строку
26           arr[0]:= arr[high(arr)];//приравняемнулевую строку последней
27           for rowN:= high(arr) downto 2 do
28           begin//для строк с последнейпо вторую
29           arr[RowN]:=arr[RowN-1];//текущаястрока равна верхней
30           end;
31           arr[1]:= tmpRow;//первуюстроку приравняем нулевой
32           end;
33           end;
 
«Разворачивание»матрицы
Процедура UnwindMatrixосуществляет «разворачивание» матрицы в одномерный массив противчасовой стрелки. Эта процедура в своих локальных переменных хранит координатытекущего элемента, текущее направление обхода (посредством перечислимого типаTDirection), а так же границы ещё не обойдённой части матрицы, которые сужаютсякаждый раз, когда проходится целая строка, или столбец. В этот же моментменяется направление обхода и текущим становится элемент в этом направлении.Обход завершается, когда число пройденных элементов станет равняться количествуэлементов в матрице:
1  //перечисление — направления
2  type TDirection = (down, right, up,left);
3  
4  {обходитматрицу arr против часовой стрелкии наполняет элементами массив res}
5  procedure UnwindMatrix(const arr:TMatrix; var res: TVector);
6  var
7  count, cur:integer;//число элементов вматрице и счётчик элементов
8  
9  RowN, ColN:integer;
10           leftB, bottomB,rightB, topB:integer;//границы обхода — меняются при проходе полной строки или столбца
11           direction: TDirection;//текущеенаправление обхода
12           
13           begin
14           if (length(arr)= 0) or (length(arr[0])= 0) thenexit;//если в матрице нет элементов — выходим
15           count:= length(arr)* length(arr[0]);//подсчитаемчисло элементов в матрице
16           SetLength(res,count);//выделим память дляхранения всех элементов матрицы
17           
18           //начальныеусловия обхода: текущий элемент [0,0], границы совпадают с граниуцами матриы,направление — вниз
19           direction:= down;
20           RowN:= 0;
21           ColN:= 0;
22           leftB:= 0;
23           bottomB:= high(arr);
24           rightB:= high(arr[0]);
25           topB:= 0;
26           
27           for cur:= 0 to count-1 do
28           begin//пока не пройдём countэлементов
29           res[cur]:=arr[RowN,ColN];//добавляем текущий элемент вмассив
30           //дальненйшиедействия зависят от текущего направления обхода
31           case direction of
32           down://если вниз
33           ifRowN
34           else
35           begin//иначе — прошли левый столбец
36           direction:= right;//сменимнаправление на «вправо»
37           inc(leftB);//сдвинемлевую границу к центру
38           inc(ColN);//сдвинемся вправо
39           end;
40           
41           right://если вправо
42           ifColN
43           else
44           begin//иначе — прошли нижнюю строку
45           direction:= up;//сменимнаправление на «вверх»
46           dec(bottomB);//сдвинемнижнюю границу к центру
47           dec(RowN);//сдвинемся вверх
48           end;
49           
50           up://если вверх
51           ifRowN > topBthen dec(RowN)//еслине дошли до верхней границы — сдвигаемся вверх
52           else
53           begin//иначе — прошли правый столбец
54           direction:= left;//сменимнаправление на «влево»
55           dec(rightB);//сдвинемправую границу к центру
56           dec(ColN);//сдвинемся влево
57           end;
58           
59           left://если влево
60           ifColN > leftBthen dec(ColN)//еслине дошли до левой границы — сдвигаемся влево
61           else
62           begin//иначе — прошли верхнюю строку
63           direction:= down;//сменимнаправление на «вниз»
64           inc(topB);//сдвинемверхнюю границу к центру
65           inc(RowN);//сдвинемся вниз
66           end;
67           end;
68           end;
69           end;
 
Сортировкастрок матрицы
Наконецупорядочивание строк матрицы по убыванию суммы элементов каждой строки.Вспомогательная функция getRowSum возвращает сумму элементов заданнойстроки:
1  {возвращаетсумму элементов RowN-ой строкиматрицы arr}
2  function getRowSum(const arr: TMatrix;RowN: integer): Int64;
3  var ColN: integer;
4  begin
5  Result:= 0;
6  ifRowN > high(arr)then exit;//еслив матрице нет RowN-ой строки — выходим
7  for ColN:= 0 to high(arr[RowN])do//суммируем элементы строки
8  Result:= Result + arr[RowN, ColN];
9  end;
Самасортировка осуществляется посредством процедуры SortRows. Был выбраналгоритм прямой вставки, так как число строк в матрице не предполагаетсябольшим, а этот алгоритм эффективен на небольших наборах данных. В любом случаесортировка осуществляется быстро, так как при перемене мест строк не происходиткопирование данных, но просто переставляются местами указатели. Листинг этойфункции:
1  {сортируетстроки матрицы по убыванию сумм элементов каждой строки}
2  procedure SortRows(var arr: TMatrix);
3  var
4  i, k:integer;//переменные дляалгоритма сортировки
5  tmpRow: TVector;//временнаяпеременная для алгоритма сортировки
6  begin
7  //алгоритмсортировки методом прямой вставки
8  for i:= 1 to high(arr) do
9  begin//для строк с первой попоследнюю
10           k:= i;//начинаяс текущей строки
11           while (k > 0) and (getRowSum(arr, k)> getRowSum(arr, k-1)) do
12           begin//пока не дошли донулевой строки, и сумма строки над текущей строкой больше текущей суммы
13           swap(arr[k-1],arr[k]);//поменяемтекущую строку и строку над ней местами
14           dec(k);//сдвинемся вверх
15           end;
16           end;
17           end;
2.3.2 Модуль fileIO
Этот модульсодержит процедуры для файлового ввода/вывода матриц. Используются текстовыефайлы, которые предварительно необходимо открыть и подготовить к чтению/записи.
Форматфайла, содержащего матрицу таков: матрица записана построчно, начиная с первойстроки, элементы в каждой строке записаны слева направо и разделеныпроизвольным количеством пробелов. Именно такой файл создаёт процедура Write2DArray:
1  {
2  записываетматрицу arr в текстовый файл outFile.Файл должен быть
3  предварительно открыт
4  }
5  procedure Write2DArray(const arr:TMatrix; const outFile: TextFile);
6  var
7  rowN, colN: integer;
8  begin
9  for rowN:= low(arr) to high(arr) do
10           begin
11           for colN:= low(arr[rowN]) tohigh(arr[rowN]) do
12           begin
13           //ширина поля 12, так как -2147483648 — 11символов
14           Write(outFile, arr[rowN, colN]: 12);
15           end;
16           Writeln(outFile);
17           end;
18           end;

Процедура Read2DArray читает файл по строкам, разбираякаждую строку на подстрока пробелами с помощью процедуры ExtractStrings:
1  {читает матрицу arr из текстовогофайла inFile. Файлдолжен быть
2  предварительно открыт}
3  procedure Read2DArray(var arr: TMatrix;const inFile: TextFile);
4  var
5  rowN, colN: integer;
6  colCount: integer;//максимальное количество чисел в строке (число столбцов матрицы)
7  lineStr: string; //текущая строка
8  strNumbers: TStringList;//текущаястрока, разделённая на подстроки пробелами
9  begin
10           rowN:= 0;
11           colCount:= 0;
12           strNumbers:= TStringList.Create;
13           arr:= nil;
14           while not Eof(inFile) do
15           begin
16           Readln(inFile, lineStr);
17           strNumbers.Clear;
18           ExtractStrings([‘ ‘], [],PChar(lineStr), strNumbers); //разделим пробелами на подстроки
19           if colCount
20           SetLength(arr, rowN+1,colCount);//выделим память под новую строку
21           for colN:= 0 to strNumbers.Count-1 do//для каждого числа в строке
22           arr[rowN, colN]:=StrToIntDef(strNumbers[colN], 0);
23           Inc(rowN);
24           end;
25           strNumbers.Destroy;
26           end;
2.3.3 Модуль form
Модуль,содержащий форму, переменную для хранения исходной матрицы, процедурысинхронизации содержания матрицы и элементов формы, а так же процедуру заданияразмеров матрицы.
Так какзадача чётко разделена на задания, оперирующие одними и теми же исходнымиданными (целочисленным двумерным массивом), было принято решение разделитьинтерфейс приложения на две части. В верхней части формы отображается матрицаисходных данных, которую можно редактировать и размеры которой можно менять.Нижняя часть формы представляет собой набор закладок, каждая из которых соответствуетодной из поставленных задач. На каждой закладке содержится описание задания,кнопка «выполнить», а так же элементы, необходимы для отображения результата врамках этого задания. Некоторые задания состоят в изменении исходной матрицы,результат выполнения таких заданий отображается непосредственно в исходныхданных в верхней части формы. Всего существует как минимум три способа выбратьзадачу: щёлкнуть мышкой по закладке, выбрать нужный пункт в меню «Задачи»,нажать одну из кнопок F1 — F5.
Опишем важныепроцедуры формы. Процедура ReadMatrix осуществляет чтение исходныхданных из таблицы на форме в двумерный массив. Перед началом чтения процедураустанавливает размер массива:
1  {заполнитьматрицу в соответствии с содержанием таблицы на форме}
2  procedure TMainForm.ReadMatrix;
3  var rowN, colN: integer;
4  begin
5  SetLength(workMatrix,G_Matrix.RowCount-1, G_Matrix.ColCount-1);
6  for rowN:= 0 to G_Matrix.RowCount-2 do
7  for colN:= 0 to G_Matrix.ColCount-2 do
8  workMatrix[rowN, colN]:=StrToIntDef(G_Matrix.Cells[colN+1, rowN+1], 0);
9  end;
Процедура writeMatrixосуществляет обратную операцию, она заполняет поля таблицы в соответствии смассивом. Кроме этого она меняет значения числа строк и столбцов в соответствиис размерами массива:
1   {заполнитьтаблицу на форме в соответствии с содержанием матрицы}
2   procedureTMainForm.writeMatrix;
3   varrowN, colN: integer;
4   begin
5   G_Matrix.Cells[1,1]:= ”;//если матрица пуста
6   E_RowsN.Text:=IntToStr(high(workMatrix) + 1);
7   if(E_RowsN.Text ‘0’) then
8   E_ColsN.Text:=IntToStr(high(workMatrix[low(workMatrix)]) + 1)
9   elseE_ColsN.Text:= ‘0’;
10           B_SetDimmsClick(self);
11           //заполним таблицу
12           for rowN:= low(workMatrix) tohigh(workMatrix) do
13           for colN:= low(workMatrix[rowN]) tohigh(workMatrix[rowN]) do
14           G_Matrix.Cells[colN+1, rowN+1]:=IntToStr(workMatrix[rowN, colN]);
15           end;
ПроцедураB_SetDimmsClick является обработчиком нажатия кнопки «задать размеры». Онапроверяет, не стали ли размеры меньше единицы, меняет число строк и столбцов втаблицах формы, а так же проставляет номера строк и столбцов:
1  {обраюотчик уствновки размеров матрицы}
2  procedureTMainForm.B_SetDimmsClick(Sender: TObject);
3  var
4  i: integer;
5  RowsN, ColsN: integer;
6  begin
7  //значенияразмеров не должны быть меньше 1
8  RowsN:= StrToIntDef(E_RowsN.Text, 0);
9  if RowsN
10           ColsN:= StrToIntDef(E_ColsN.Text, 0);
11           if ColsN
12           //числострок и столбцов в таблице, учитывая колонку и строку с номерами
13           G_Matrix.RowCount:= RowsN + 1;
14           G_Matrix.ColCount:= ColsN + 1;
15           //вэтих таблицах отображаются одномерные массивы из первого задания
16           G_Task1B.RowCount:= RowsN;
17           G_Task1C.RowCount:= RowsN;
18           //одномерныймассив из четвёртого задания имеет длину, равную числу элементов исходнойматрицы
19           G_Task4.ColCount:= RowsN * ColsN;
20           //расставим номера строк и столбцов
21           for i:= 0 to RowsN do
22           begin
23           G_Matrix.Cells[0, i+1]:= IntToStr(i+1);
24           G_Task1B.Cells[0, i]:= IntToStr(i+1);
25           G_Task1C.Cells[0, i]:= IntToStr(i+1);
26           end;
27           for i:= 0 to ColsN do
28           G_Matrix.Cells[i+1, 0]:= IntToStr(i+1);
29           for i:= 0 to RowsN * ColsN do
30           G_Task4.Cells[i, 0]:= IntToStr(i+1);
31           G_Matrix.Refresh;
32           end;
Процедура FormDestroy выполняется при уничтожении формы ивыполняет очень важную функцию – освобождает память, которая выделялась вовремя работы приложения под матрицу исходных данных.
ПроцедураsaveClick является обработчиком щелчка по пункту меню Файл->Сохранить. Онаотображает диалог выбора файла для сохранения, создаёт выбранный файл, а послеокончания записи закрывает его:
1  {обработчик Файл->Сохранить}
2  procedure TMainForm.saveClick(Sender:TObject);
3  var
4  outFile: TextFile;
5  begin
6  //отобразимдиалог выбора файла для сохранения, если отмена — выходим
7  if SaveDialog.Execute = false then exit;
8  AssignFile(outFile,SaveDialog.Files[0]);
9  ReWrite(outFile);//создадим файл
10            readMatrix;//прочтёмматрицу из таблицы
11           Write2DArray(workMatrix,outFile);//запишем матрицу в файл
12           CloseFile(outFile);//закроем файл.

ПроцедураloadClick ведёт себя так же, только не создаёт файл, а открывает его длячтения:
1  {обработчик Файл->Загрузить}
2  procedure TMainForm.loadClick(Sender:TObject);
3  var
4  inFile: TextFile;
5  begin
6  //отобразимдиалог выбора фала для загрузки, если отмена — выходим
7  if OpenDialog.Execute = false then exit;
8  AssignFile(inFile, OpenDialog.Files[0]);
9  Reset(inFile);//подготовимфайл к чтению
10           Read2DArray(workMatrix,inFile);//прочтём матрицу изфайла
11           writeMatrix;//отобразим матрицу
12           CloseFile(inFile);//закроем файл
13           end;
Остальныепроцедуры просто вызывают процедуры и функции других модулей, наполняютрезультатами соответствующие заданию элементы формы, а в конце обязательноосвобождают динамическую память, если таковая была выделена в рамках процедуры.
2.4 Описание формата исходных файлов
Матрица висходном файле представляется в текстовом виде. Каждая строка матрицы начинаетсяс новой строки. Каждый элемент строки отделён от других произвольным числомпробелов и должен быть представлен целым числом, лежащим в диапазоне[-2147483648; 2147483647]. Если какой-то элемент выходит за границы этогодиапазона, либо не является целым числом, то он интерпретируется как ноль.
Примерправильно составленного исходного файла:
100000  10000     20000    40000     -4000
50           100        -20         1000        2000
-100        -50         -20          0               20
-1000      -200        200        2              12
4000       -100000-40000  -10000        80000

3. Эксплуатационная документация
 
3.1 Описание применения
Программапредназначена для выполнения определённого набора операций над матрицами.Описание каждой операции можно прочесть на соответствующей вкладке в интерфейсепрограммы.
Программапредназначена для исполнения на IBM-совместимыхкомпьютерах с операционной системой Windows (тестирование проводилось на Windows XP).
Минимальныесистемные требования:
·         Дисплей сразрешением 1024×768
·         Клавиатура
·         10 мегабайтсвободной оперативной памяти
Требованияприложения к оперативной памяти сильно зависят от размера обрабатываемойматрицы. Соответствующий минимальным требованиям компьютер сможет обрабатыватьматрицы размером не менее ста элементов.
Входнымипараметрами для приложения являются файлы, описанные в пункте 3.4. Так же естьвозможность ввести исходную матрицу непосредственно в таблицу на форме.
Выходныеданные представляются в элементах формы, расположенных на соответствующейзаданию вкладке (смотрите руководство оператора)
3.2 Руководство оператора
Интерфейсприложения разделён на две части. В верхней части формы отображается матрицаисходных данных, которую можно редактировать и размеры которой можно менять.Нижняя часть формы представляет собой набор закладок, каждая из которыхсоответствует одной из поставленных задач. На каждой закладке содержитсяописание задания, кнопка «выполнить», а так же элементы, необходимы дляотображения результата в рамках этого задания. Некоторые задания состоят визменении исходной матрицы, результат выполнения таких заданий отображаетсянепосредственно в исходных данных в верхней части формы. Всего существует какминимум три способа выбрать задачу: щёлкнуть мышкой по закладке, выбрать нужныйпункт в меню «Задачи», нажать одну из кнопок F1 — F5.
Открытиефайла с данными:
/>

Выполнениезадачи №1:
/>
Результатвыполнения задачи №1:

/>
Переход кзадаче №3:
/>

Выполнениезадачи №3:
/>
Результатдвукратного выполнения задачи №3:
/>

Результатвыполнения задачи №2:
/>
Результатвыполнения задачи №5:
/>

Результатвыполнения задачи №4:
/>

Сохранениеполученной матрицы в файл:
/>

Завершениеработы программы:
/>
Содержаниесохранённого файла:
100000    10000   20000    40000    -4000
50            100       -20       1000       2000
-100         -50       -20        0             20
-1000      -200      200        2            12
4000    -100000  -40000  -10000     80000

Выводы
Двумерныйдинамический массив – очень удобная конструкция для представления матрицы,размеры которой во время написания программы не известны. Но при егоиспользовании нужно быть осторожным и учитывать некоторые особенности:
·         При вызове SetLength с одним параметром размера будетвыделена память только под первую размерность массива (например, будетувеличено число строк в матрице), остальные размерности затронуты не будут (вкаждой добавленной строке будет ноль элементов).
·         Каждый подмассивмногомерного массива может иметь свою размерность (например, каждая строкаматрицы в общем то может иметь длину, отличную от других)
·         Необходимо всегдазнать границы каждой размерности, чтобы не выйти за пределы массива в чужуюпамять. Для этого полезны функции low и high.
·         Необходимо всегдаосвобождать динамически выделенную память.
·         При присваиваниидинамических массивов копирования данных не происходит, присваиваются лишьуказатели, таким образом, после присваивания два массива будут указывать наодну и ту же область памяти. Чтобы получить копию массива, можно использоватьфункцию Copy.
·         Copy копирует не весь многомерный массив,но только его первую размерность.

Приложения
 
Приложение 1. Тестовые примеры
 
Тест 1:Квадратная матрица 5×5.
Исходнаяматрица:
-100       -50           -20          0            20
50          100           200        1000      2000
4000      10000       20000    40000   80000
100000 -100000   -40000    -10000   -4000
-1000    -200        -20            2            12
Результатвыполнения первого задания:
Максимальныеэлементы по строкам: 20; 2000; 80000; 100000; 12
Столбцы смаксимальными элементами: 5; 5; 5; 1; 5
Результатвыполнения второго задания:
S1 = 130
S2 = -40218
S1 > S2, матрица не была изменена
Результатвыполнения третьего задания:
Числостолбцов нечётно – был произведён сдвиг «вниз»
-1000          -200          -20         2        12
-100            -50            -20         0        20
50               100            200       1000   2000
4000          10000        20000    40000 80000
100000     -100000     -40000   -10000 -4000
Результатвыполнения четвёртого задания:
Матрица,«развёрнутая» против часовой стрелки: -100; 50; 4000; 100000; -1000; -200; -20;2; 12; -4000; 80000; 2000; 20; 0; -20; -50; 100; 10000; -100000; -40000;-10000; 40000; 1000; 200; 20000
Результатвыполнения пятого задания:
Строкиотсортированы в невозрастающем порядке сумм:
4000         10000        20000         40000    80000
50             100            200             1000      2000
-100         -50            -20                0            20
-1000        -200         -20                2            12
100000   -100000    -40000         -10000    -4000
Тест 2:прямоугольная матрица 3×8.
Исходнаяматрица:
1-   18    17 -16      15         -14             13                -12
-2   19   20  2000  200000  20000000  2000000000  11
3    -4     5   -6       7           -8                9                   -10
Результатвыполнения первого задания:
Максимальныеэлементы по строкам: 17; 2000000000; 9
Столбцы смаксимальными элементами: 3; 7; 7
Результатвыполнения второго задания:
S1 = -18 S2 = -4
S1
1   -4   17  -16    15         -14             13                -12
-2 19  20  2000  200000  20000000  2000000000  11
3 -18   5  -6        7           -8                9                   -10

Результатвыполнения третьего задания:
Число столбцовчётно – был произведён сдвиг «вверх»
-2 19   20   2000   200000  20000000   2000000000  11
3  -18  5     -6        7           -8                9                    -10
1   -4   17   -16      15         -14              13                  -12
Результатвыполнения четвёртого задания:
Матрица,«развёрнутая» против часовой стрелки: 1; -2; 3; -4; 5; -6; 7; -8; 9; -10; 11;-12; 13; -14; 15; -16; 17; -18; 19; 20; 2000; 200000; 20000000; 2000000000;
Результатвыполнения пятого задания:
Строкиотсортированы в невозрастающем порядке сумм:
-2 19  20  2000  200000  20000000  2000000000  11
3  -4   5    -6       7           -8                9                    -10
1  -18  17 -16     15         -14              13                  -12
Тест 3:прямоугольная матрица 10×5, наполненная случайными числами.
Исходнаяматрица:
4490    6540  -12901 20330  -6046
-27459-22256 26705 14852 -30502
23701-11502 -30162 -14325 -20739
-15721-14704 17504 -23934 21020
-279327054 -30557 -28698 -19302
-16794-24715 28069 -2485 -11281
3072718102 20673 -32373 23140
-16762-1303 5821 21065 -25295
-2447227091 -6385 -13002 -22009
-1230926284 20788 -21316 -25044
Результатвыполнения первого задания:
Максимальныеэлементы по строкам: 20330; 26705; 23701; 21020; 7054
Столбцы смаксимальными элементами: 4; 3; 1; 5; 2
Результатвыполнения второго задания:
S1 = 4934
S2 = -21774
S1 > S2, матрица не была изменена
Результатвыполнения третьего задания:
Числостолбцов нечётно – был произведён сдвиг «вниз»
-1230926284 20788 -21316 -25044
4490   6540 -12901  20330 -6046
-27459-22256 26705 14852 -30502
23701-11502 -30162 -14325 -20739
-15721-14704 17504 -23934 21020
-279327054 -30557 -28698 -19302
-16794-24715 28069 -2485 -11281
3072718102 20673 -32373 23140
-16762-1303 5821 21065 -25295
-2447227091 -6385 -13002 -22009
Результатвыполнения четвёртого задания:
Матрица,«развёрнутая» против часовой стрелки: 4490; -27459; 23701; -15721; -27932;-16794; 30727; -16762; -24472; -12309; 26284; 20788; -21316; -25044; -22009;-25295; 23140; -11281; -19302; 21020; -20739; -30502; -6046; 20330; -12901;6540; -22256; -11502; -14704; 7054; -24715; 18102; -1303; 27091; -6385; -13002;21065; -32373; -2485; -28698; -23934; -14325; 14852; 26705; -30162; 17504;-30557; 28069; 20673; 5821
Результатвыполнения пятого задания:
Строкиотсортированы в невозрастающем порядке сумм:
3072718102 20673 -32373 23140
44906540 -12901 20330    -6046
-1230926284 20788 -21316 -25044
-15721-14704 17504 -23934 21020
-16762-1303 5821 21065     -25295
-16794-24715 28069 -2485 -11281
-27459-22256 26705 14852 -30502
-2447227091 -6385 -13002 -22009
23701-11502 -30162 -14325 -20739
-279327054 -30557 -28698 -19302
Тест 4:матрица с большими по модулю числами.
Исходнаяматрица:
0                   -2000000000  -2100000000  -2000000000  1
1000000000 -800000000     400000000      3                   15
0                   -2000000000  -2000000000   -2000000000  1
1000000000 -800000000     400000000      3                    15
0                   -2000000000  -2000000000   -2000000000  1
1000000000 -800000000     400000000       3                   15
0                   -2000000000  -1900000000    -200000000   1
Результатвыполнения первого задания:
Максимальныеэлементы по строкам: 1; 1000000000; 1; 1000000000; 1; 1000000000; 1
Столбцы смаксимальными элементами: 5; 1; 5; 1; 5; 1; 5
Результатвыполнения второго задания:
S1 = -7699999981
S2 = -7499999981
S1
0                  -2000000000  -1900000000  -2000000000   1
1000000000-800000000    400000000      3                     15
0                  -2000000000 -2000000000   -2000000000    1
1000000000-800000000    400000000       3                      15
0                  -2000000000  -2000000000   -2000000000    1
1000000000-800000000     400000000      3                      15
0                  -2000000000  -2100000000   -2000000000     1
Результатвыполнения третьего задания:
Числостолбцов нечётно – был произведён сдвиг «вниз»
0                     -2000000000  -1900000000   -2000000000    1
0                     -2000000000  -2100000000   -2000000000    1
1000000000   -800000000    400000000       3                       15
0                     -2000000000  -2000000000    -2000000000    1
1000000000   -800000000    400000000        3                       15
0                     -2000000000  -2000000000    -2000000000     1
1000000000   -800000000    400000000        3                      15
Результатвыполнения четвёртого задания:
Матрица,«развёрнутая» против часовой стрелки: 0; 1000000000; 0; 1000000000; 0;1000000000; 0; -2000000000; -1900000000; -2000000000; 1; 15; 1; 15; 1; 15; 1;-2000000000; -2100000000; -2000000000; -800000000; -2000000000; -800000000;-2000000000; -800000000; 400000000; 3; -2000000000; 3; -2000000000; 3;400000000; -2000000000; 400000000; -2000000000
Результатвыполнения пятого задания:
Строкиотсортированы в невозрастающем порядке сумм:
1000000000   -800000000     400000000   3                          15
1000000000   -800000000     400000000   3                            15
1000000000   -800000000     400000000   3                            15
0                     -2000000000  -1900000000 -2000000000          1
0                     -2000000000  -2000000000 -2000000000          1
0                     -2000000000  -2000000000 -2000000000          1
0                     -2000000000  -2100000000 -2000000000          1
Тест 5:матрица с ошибками.
Исходнаяматрица:
9999999999123 fdf
456rt 8888888888
12345678909876543210 789
q0xf e
-77777777777000 -13
915-376 19
ddd-ddd 1111111111
Внутрипрограммы такая матрица будет интерпретирована следующим образом:
0                    123    0
456                 0       0
1234567890   0      789
0                     15      0
0                     0        -13
915                -376     19
0                     0           1111111111
Результатвыполнения первого задания:
Максимальныеэлементы по строкам: 123; 456; 1234567890; 15; 0; 915; 1111111111
Столбцы смаксимальными элементами: 2; 1; 1; 2; 1; 1; 3
Результатвыполнения второго задания:
S1 = 123
S2 = 1111111130
S1
0                        0          1111111111
456                    0          19
1234567890      0          789
0                       15          0
0                       0             -13
915                 -376            0
0                     123              0
Результатвыполнения третьего задания:
Числостолбцов нечётно – был произведён сдвиг «вниз»
0                       0        1111111111
0                       123     0
456                   0         0
1234567890     0         789
0                      15        0
0                      0         -13
915               -376           19
Результатвыполнения четвёртого задания:
Матрица,«развёрнутая» против часовой стрелки: 0; 456; 1234567890; 0; 0; 915; 0; 0;1111111111; 19; -13; 0; 789; 0; 0; 123; 0; 0; 15; 0; -376
Результатвыполнения пятого задания:
Строкиотсортированы в невозрастающем порядке сумм:
1234567890              0            789
0                                0            1111111111
915                          -376         19
456                           0             0
0                               123         0
0                               15            0
0                               0            -13

Приложение 2. Полный листинг формы(файл form.pas)
 
14         {
15         Модуль, содержащий форму, переменную дляхранения исходной матрицы,
16         процедуры синхронизации содержанияматрицы и элементов формы, а так же
17         процедуру задания размеров матрицы
18         }
19         unit form;
20         
21         interface
22         
23         uses
24         Windows, Messages, SysUtils, Variants, Classes,Graphics, Controls, Forms,
25         Dialogs, Menus, StdCtrls, ExtCtrls,ComCtrls, Grids,
26         //модули программы
27         fileIO, MatrixOperations;
28         
29         type
30         TMainForm = class(TForm)
31         Pages: TPageControl;
32         Task1: TTabSheet;
33         Task2: TTabSheet;
34         Task3: TTabSheet;
35         Task4: TTabSheet;
36         Task5: TTabSheet;
37         Menu: TMainMenu;
38         A1: TMenuItem;
39         load: TMenuItem;
40         save: TMenuItem;
41         N1: TMenuItem;
42         quit: TMenuItem;
43         N4: TMenuItem;
44         M_Task1: TMenuItem;
45         M_Task2: TMenuItem;
46         M_Task3: TMenuItem;
47         M_Task4: TMenuItem;
48         M_Task5: TMenuItem;
49         GroupBox1: TGroupBox;
50         G_Matrix: TStringGrid;
51         E_RowsN: TEdit;
52         Label1: TLabel;
53         Label2: TLabel;
54         E_ColsN: TEdit;
55         B_SetDimms: TButton;
56         SaveDialog: TSaveDialog;
57         OpenDialog: TOpenDialog;
58         Label3: TLabel;
59         Label4: TLabel;
60         G_Task1B: TStringGrid;
61         Label5: TLabel;
62         Label6: TLabel;
63         G_Task1C: TStringGrid;
64         B_Task1Run: TButton;
65         Label7: TLabel;
66         Label8: TLabel;
67         Label9: TLabel;
68         E_Task2S1: TEdit;
69         B_Task2Run: TButton;
70         E_Task2S2: TEdit;
71         L_Task2MatrxChanged: TLabel;
72         Label10: TLabel;
73         B_Task3Run: TButton;
74         L_Task3Result: TLabel;
75         Label11: TLabel;
76         B_Task4Run: TButton;
77         Label12: TLabel;
78         B_Task5Run: TButton;
79         about: TMenuItem;
80         MEM_Task4: TMemo;
81         procedure saveClick(Sender: TObject);
82         procedure loadClick(Sender: TObject);
83         procedure B_SetDimmsClick(Sender:TObject);
84         procedure FormCreate(Sender: TObject);
85         procedure quitClick(Sender: TObject);
86         procedure M_Task1Click(Sender: TObject);
87         procedure M_Task2Click(Sender: TObject);
88         procedure M_Task3Click(Sender: TObject);
89         procedure M_Task4Click(Sender: TObject);
90         procedure M_Task5Click(Sender: TObject);
91         procedure B_Task1RunClick(Sender:TObject);
92         procedure FormDestroy(Sender: TObject);
93         procedure B_Task2RunClick(Sender:TObject);
94         procedure B_Task3RunClick(Sender:TObject);
95         procedure B_Task4RunClick(Sender:TObject);
96         procedure B_Task5RunClick(Sender:TObject);
97         procedure aboutClick(Sender: TObject);
98         private
99         procedure readMatrix;
100      procedure writeMatrix;
101      public
102      published
103      { Public declarations }
104      end;
105      
106      var
107      MainForm: TMainForm;
108      workMatrix: TMatrix;
109      
110      implementation
111      
112      uses Math;
113      
114      {$R *.dfm}
115      
116      {заполнить матрицу в соответствии ссодержанием таблицы на форме}
117      procedure TMainForm.ReadMatrix;
118      var rowN, colN: integer;
119      begin
120      SetLength(workMatrix,G_Matrix.RowCount-1, G_Matrix.ColCount-1);
121      for rowN:= 0 to G_Matrix.RowCount-2 do
122      for colN:= 0 to G_Matrix.ColCount-2 do
123      workMatrix[rowN, colN]:=StrToIntDef(G_Matrix.Cells[colN+1, rowN+1], 0);
124      end;
125      
126      {заполнить таблицу на форме всоответствии с содержанием матрицы}
127      procedure TMainForm.writeMatrix;
128      var rowN, colN: integer;
129      begin
130      G_Matrix.Cells[1, 1]:= ”;//если матрицапуста
131      //обновим размеры матрицы
132      E_RowsN.Text:= IntToStr(high(workMatrix)+ 1);
133      if(E_RowsN.Text ‘0’) then
134      E_ColsN.Text:= IntToStr(high(workMatrix[low(workMatrix)])+ 1)
135      else E_ColsN.Text:= ‘0’;
136      B_SetDimmsClick(self);
137      //заполним таблицу
138      for rowN:= low(workMatrix) tohigh(workMatrix) do
139      for colN:= low(workMatrix[rowN]) tohigh(workMatrix[rowN]) do
140      G_Matrix.Cells[colN+1, rowN+1]:=IntToStr(workMatrix[rowN, colN]);
141      end;
142      
143      {обработчик Файл->Сохранить}
144      procedure TMainForm.saveClick(Sender:TObject);
145      var
146      outFile: TextFile;
147      begin
148      //отобразим диалог выбора файла длясохранения, если отмена — выходим
149      if SaveDialog.Execute = false then exit;
150      AssignFile(outFile,SaveDialog.Files[0]);
151      ReWrite(outFile);//создадим файл
152      
153      readMatrix;//прочтём матрицу из таблицы
154      Write2DArray(workMatrix,outFile);//запишем матрицу в файл
155      
156      CloseFile(outFile);//закроем файл
157      
158      end;
159      
160      {обработчик Файл->Загрузить}
161      procedure TMainForm.loadClick(Sender:TObject);
162      var
163      inFile: TextFile;
164      begin
165      //отобразим диалог выбора фала длязагрузки, если отмена — выходим
166      if OpenDialog.Execute = false then exit;
167      AssignFile(inFile, OpenDialog.Files[0]);
168      Reset(inFile);//подготовим файл к чтению
169      
170      Read2DArray(workMatrix,inFile);//прочтём матрицу из файла
171      writeMatrix;//отобразим матрицу
172      
173      CloseFile(inFile);//закроем файл
174      end;
175      
176      {обраюотчик уствновки размеров матрицы}
177      procedureTMainForm.B_SetDimmsClick(Sender: TObject);
178      var
179      i: integer;
180      RowsN, ColsN: integer;
181      begin
182      //значения размеров не должны бытьменьше 1
183      RowsN:= StrToIntDef(E_RowsN.Text, 0);
184      if RowsN
185      ColsN:= StrToIntDef(E_ColsN.Text, 0);
186      if ColsN
187      //число строк и столбцов в таблице,учитывая колонку и строку с номерами
188      G_Matrix.RowCount:= RowsN + 1;
189      G_Matrix.ColCount:= ColsN + 1;
190      //в этих таблицах отображаютсяодномерные массивы из первого задания
191      G_Task1B.RowCount:= RowsN;
192      G_Task1C.RowCount:= RowsN;
193      //одномерный массив из четвёртогозадания имеет длину, равную числу элементов исходной матрицы
194      //G_Task4.ColCount:= RowsN * ColsN;
195      //расставим номера строк и столбцов
196      for i:= 0 to RowsN do
197      begin
198      G_Matrix.Cells[0, i+1]:= IntToStr(i+1);
199      G_Task1B.Cells[0, i]:= IntToStr(i+1);
200      G_Task1C.Cells[0, i]:= IntToStr(i+1);
201      end;
202      for i:= 0 to ColsN do
203      G_Matrix.Cells[i+1, 0]:= IntToStr(i+1);
204      
205      //for i:= 0 to RowsN * ColsN do
206      // G_Task4.Cells[i, 0]:= IntToStr(i+1);
207      G_Matrix.Refresh;
208      end;
209      
210      {при создании формы задаём размерматрицы по умолчанию}
211      procedure TMainForm.FormCreate(Sender:TObject);
212      begin
213      B_SetDimmsClick(Sender);
214      end;
215      
216      {при уничтожении формы освобождаемпамять, выделенную для хранения матрицы}
217      procedure TMainForm.FormDestroy(Sender:TObject);
218      begin
219      workMatrix:= nil;
220      end;
221      
222      {обработчик Файл->Выход}
223      procedure TMainForm.quitClick(Sender:TObject);
224      begin
225      if mrYes = MessageDlg(‘Вы уверены, чтохотите выйти?’, mtConfirmation, [mbYes, mbNo], 0)
226      then Close;
227      end;
228      
229      {обработчик Задачи->задача 1}
230      procedure TMainForm.M_Task1Click(Sender:TObject);
231      begin
232      Pages.ActivePageIndex:= 0;
233      end;
234      {обработчик Задачи->задача 2}
235      procedure TMainForm.M_Task2Click(Sender:TObject);
236      begin
237      Pages.ActivePageIndex:= 1;
238      end;
239      {обработчик Задачи->задача 3}
240      procedure TMainForm.M_Task3Click(Sender:TObject);
241      begin
242      Pages.ActivePageIndex:= 2;
243      end;
244      {обработчик Задачи->задача 4}
245      procedure TMainForm.M_Task4Click(Sender:TObject);
246      begin
247      Pages.ActivePageIndex:= 3;
248      end;
249      {обработчик Задачи->задача 5}
250      procedure TMainForm.M_Task5Click(Sender:TObject);
251      begin
252      Pages.ActivePageIndex:= 4;
253      end;
254      
255      {выполнение первого задания}
256      procedureTMainForm.B_Task1RunClick(Sender: TObject);
257      var
258      maxVal: TVector; //массив максимальныхэлементов из каждой строки
259      maxValCol: TVector; //массив номеровстолбцов с максимальными элементами
260      RowN: integer;
261      begin
262      readMatrix;//прочитаем матрицу изтаблицы
263      GetMaxVals(maxVal, maxValCol,workMatrix);//сформируем массивы по заданию
264      for RowN:= low(maxVal) to high(maxVal)do
265      begin//выведем сформированные массивы вэлементы формы
266      G_Task1B.Cells[1, RowN]:=IntToStr(maxVal[RowN]);
267      G_Task1C.Cells[1, RowN]:=IntToStr(maxValCol[RowN]+1);
268      end;
269      //освободим память
270      maxVal:= nil;
271      maxValCol:= nil;
272      end;
273      
274      {выполнение второго задания}
275      procedure TMainForm.B_Task2RunClick(Sender:TObject);
276      var S1, S2: Int64;//суммы выше и нижепересечения диагоналей
277      begin
278      readMatrix;//проситаем матрицу изтаблицы
279      //высчитаем суммы
280      S1:= GetSumAbove(workMatrix);
281      S2:= GetSumBelow(workMatrix);
282      //выведем суммы в элементы формы
283      E_Task2S1.Text:= IntToStr(S1);
284      E_Task2S2.Text:= IntToStr(S2);
285      if S1 >= S2 thenL_Task2MatrxChanged.Caption:= ‘Матрица не была изменена’
286      else
287      begin//если S1
288      SwapAboveBelow(workMatrix);//меняем местамиэлементы выше и ниже пересечения диагоналей
289      writeMatrix;//выводим изменённую матрицуна форму
290      L_Task2MatrxChanged.Caption:= ‘Матрицабыла изменена’
291      end;
292      end;
293      
294      {выполнение третьего задания}
295      procedure TMainForm.B_Task3RunClick(Sender:TObject);
296      begin
297      readMatrix;//прочтём матрицу из таблицы
298      if (high(workMatrix)+1) mod 2 = 0 then
299      begin//если число строк — чётное
300      CircuarShift(workMatrix,true);//осуществим циклический сдвиг вверх
301      L_Task3Result.Caption:= ‘был произведёнсдвиг «вверх»’;
302      end
303      else
304      begin//иначе, если число строк — нечётное
305      CircuarShift(workMatrix,false);//осуществим циклический сдвиг вниз
306      L_Task3Result.Caption:= ‘был произведёнсдвиг «вниз»’;
307      end;
308      writeMatrix;//выведем изменённую матрицув таблицу
309      end;
310      
311      {выполнение четвёртого задания}
312      procedureTMainForm.B_Task4RunClick(Sender: TObject);
313      var arrayB: TVector;//массив, содержащий«развёрнутую» матрицу
314      var i: integer;
315      begin
316      readMatrix;//прочтём матрицу из таблицы
317      UnwindMatrix(workMatrix,arrayB);//наполним массив, обходя матрицу по спирали
318      MEM_Task4.Lines[0]:= ”;
319      for i:= 0 to high(arrayB) do
320      begin//выведем все элементы из массивана форму
321      //G_Task4.Cells[i, 1]:= IntToStr(arrayB[i]);
322      MEM_Task4.Lines[0]:= MEM_Task4.Lines[0]+ IntToStr(arrayB[i]) + ‘; ‘
323      end;
324      arrayB:= nil;//освободим память
325      end;
326      
327      {выполнение пятого задания}
328      procedureTMainForm.B_Task5RunClick(Sender: TObject);
329      begin
330      readMatrix;//прочтём матрицу из таблицы
331      SortRows(workMatrix);//отсортируемстроки матрицы по убыванию сумм
332      writeMatrix;//выведем матрицу в таблицу
333      end;
334      {обработчик About}
335      procedure TMainForm.aboutClick(Sender:TObject);
336      var info: string;
337      begin
338      info:= ‘Курсовая работа по дисциплине«Программирование на ЯВУ»’#10#10 +
339      ‘Тема: «Работа с двумернымичисловыми массивами»’#10 +
340      ‘Выполнил: студент группы ВСМ-06-08Филон Д. В.’#10#10#10 +
341      #9#9#9#9#9#9’Москва 2010 год’;
342      MessageDlg(info, mtInformation,[mbIgnore], 0);
343      end;
344      end.