Содержание
Введение
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).
Минимальныесистемные требования:
· Дисплей сразрешением 1024x768
· Клавиатура
· 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:Квадратная матрица 5x5.
Исходнаяматрица:
-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:прямоугольная матрица 3x8.
Исходнаяматрица:
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:прямоугольная матрица 10x5, наполненная случайными числами.
Исходнаяматрица:
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.