Программирование.
Часть 2.
5. Процедура
сортировки
Ниже на рис. 6. приведена
процедура SortArr1 сортировки одномерного
динамического массива по "методу пузырька"
и вспомогательная процедура Revers обмена
значениями двух переменных.
procedure Revers(var
a,b: Real);
// перестановка значений переменных a и b
var z: Real;
begin
z:=a;
a:=b;
b:=z;
end;
procedure SortArr1(var a: TArr1);
// сортировка одномерного массива a,
// размер массива определяется автоматически
var i,j: Integer; L: boolean;
begin
if Length(a)>2 then // нужно
сортировать
repeat // начало цикла
L:=true;
for i:=1 to Length(a)-2 do
if (a[i]>a[i+1]) then
begin
Revers(a[i],a[i+1]); //перестановка
несортированной пары
L:=false;
end;
until L; // конец цикла
end; |
Рис. 6.
Текст процедур Revers и SortArr1
Поясним работу процедуры SortArr1.
При входе в нее сначала проверяется длина
сортирумого массива с именем a. Если в нем
элементов более двух, то начинается сортировка.
Поскольку элемент a[0] нами не используется, то это
значит, что в массиве есть по крайней мере 2
элемента, следовательно есть что
сортировать.
Сортировка производится
многократным выполнением оператора цикла repeat
- until. Внутри него булева переменная L сначала
принимает истинное значение (true). Это означает,
что перед изучением состояния массива мы
предполагаем, что он отсортирован.
Далее внутри цикла
выполняется еще один цикл for - do, который
предназначен для прохода по всем парам соседних
элементов массива. В том случае, когда какая-либо
пара оказывается неотсоритрованной, ее значения
меняются местами при помощи процедуры Revers,
а переменной L присваивается ложное значение
(false). Для процедуры это сигнал, что произошла
перестановка и что наше предположение об
отсортированности не оправдалось и процесс
сортировки следует продолжить. Цикл repeat - until
выполняется до тех пор, пока все пары соседних
элементов не будут отсортированы. В этом случае
будет отсортирован и весь массив a.
Вставьте текст этих
процедур в модуль main.pas вслед за ранее
подготовленным текстом.
6. Процедура
сортировки строк матрицы А и формирования
массива U
Ниже на рис. 7. приведена
процедура с именем Arr2SortAndFormU сортировки строк матрицы А и
формирования массива U из наибольших элементов
отсортированных строк массива А. Вставьте ее в
текст модуля main.pas.
procedure Arr2SortAndFormU;
// сортировка строк двумерного массива А
// и формирование одномерного массива U
// из наибольших элементов строк массива А
var i,j: Integer;
begin
SetLength(u,n+1);
for i:= 1 to Length(a)-1 do //
проход по строкам А
begin
SortArr1(a[i]); // сортировка i-строки массива A
u[i]:=a[i,m]; // передача набольшего
элемента в U
end;
end; |
Рис. 7.
Процедура сортировки строк матрицы и
формирования массива U
Процедура сначала
устанавливает длину массива U при помощи функции
SetLength, резервируя у компьютера n+1 ячейку, т. к.
нулевой элемент u[0] мы не используем. Далее в
цикле for - do при помощи процедуры SortArr1
происходит сортировка каждой строки a[i] матрицы a
для всякого значения счетчика цикла i. После
сортировки наибольший элемент строки копируется
в соответствующую ячейку массива U и цикл
приступает к обработке следующей строки. В
результате работы этого цикла все строки матрицы
А окажутся отсортированными и будет сформирован
массив U. Он пока лишь сформирован, но еще не
отсортирован.
7. Пограммирование
события от щелчка на строке меню "Выполнить"
Теперь запрограммируем
процесс, ради которого нами выполнены ранее
перечисленные подготовительные работы. Верните
наверх форму и щелкните в меню на строке Выполнить.
Вставьте в заготовку процедуры-обработчика,
созданную Delphi, внутренню часть,
представленную на рис. 8.
procedure
TfMain.mmExecuteClick(Sender: TObject);
// Эта процедура решает задачу в целом
begin
n:=SpinEdit1.Value; // считывание количества строк А
m:=SpinEdit2.Value; // считывание количества столбцов
А
Memo2.Clear; // очистка редактора Memo2
if FormVspomArrToA then // передача
исходных данных в матрицу А
begin
OutStr('Исходная матрица A:'); // вывод
пояняющего заголовка
OutArr2(a,7,2); // вывод исходного массива А
Arr2SortAndFormU; // сортировка строк А и
формирование U
OutStr('Матрица A после сортировки строк:');
// надпись
OutArr2(a,7,2); // вывод отсортированного
массива А
OutStr('Массив U до сортировки:'); // надпись
OutArr1(u,7,2); // вывод исходного массива U
SortArr1(u); // сортировка массива U
OutStr('Массив U после сортировки:'); //
надпись
OutArr1(u,7,2); // вывод отсортированного
массива U
end;
end; |
Рис. 8.
Текст обработчика события на щелчок по строке
меню Выполнить
Действия, которые будут
выполнены этой процедуры, должны быть понятны из
сопутствующих каждому оператору комментариев.
8. Пограммирование
сервисных событий
Запрограммируем события,
которые носят сервисный характер.
8.1. Сохранение
данных в файле
Щелкните на строке меню Файл/Сохранить
и вставьте в заготовку процедуры обработчика
текст так, чтобы она приняла вид рис. 9.
procedure
TfMain.mmSaveClick(Sender: TObject);
// сохранение данных из Memo1 в файле 'Datas.txt'
begin
if DaNet('Сохранить исходные данные из
Memo1 ?')
then Memo1.Lines.SaveToFile(df);
end; |
Рис. 9.
Текст обработчика события на щелчок по строке
меню Файл/Сохранить
Эта процедура позволит
сохранить данные, находящиеся в Memo1, в
файле Datas.txt в папке
проекта. Обратите внимание, что перед
сохранением данных процедура задает уточняющий
вопрос: это необходимо для того, чтобы случайно
щелкнув на этой строке меню, пользователь по
ошибке не изменил данные.
8.2. Вызов
данных из файла
Щелкните на строке меню Файл/Открыть
и вставьте в заготовку процедуры обработчика
текст так, чтобы она приняла вид рис. 10.
procedure
TfMain.mmOpenClick(Sender: TObject);
// чтение данных из файла 'Datas.txt' в Memo1
begin
if FileExists(df) then
Memo1.Lines.LoadFromFile(df);
end; |
Рис. 9.
Текст обработчика события на щелчок по строке
меню Файл/Открыть
Эта процедура позволяет
вызвать в Memo1 ранее сохраненные данные в файле Datas.txt.
8.3. Очистка Memo1
Щелкните на строке меню Файл/Очистить
Memo1 и вставьте в заготовку процедуры
обработчика текст так, чтобы она приняла вид рис.
11.
procedure
TfMain.mmClear1Click(Sender: TObject);
// очистка Memo1
begin
if DaNet('Очистить Memo1 ?') then Memo1.Clear;
end; |
Рис. 11.
Текст обработчика события на щелчок по строке
меню Файл/Очистить Memo1
Очищает Memo1. Перед очисткой
предварительно задает уточняющий вопрос.
8.4. Очистка Memo2
Щелкните на строке меню Файл/Очистить
Memo2 и вставьте в заготовку процедуры
обработчика текст так, чтобы она приняла вид рис.
12.
procedure
TfMain.mmClear2Click(Sender: TObject);
// очистка Memo2
begin
Memo2.Clear;
end; |
Рис. 12.
Текст обработчика события на щелчок по строке
меню Файл/Очистить Memo2
Очищает Memo2. Задавать
уточняющий вопрос не нужно, т. к. данные Memo2 можно
всегда вернуть, выпонив команду Выполнить.
9. Пограммирование
процедур закрытия приложения
В заключение
запрограммируем события, которые нужно
выполнить при закрытии приложения.
9.1. Закрытие
приложения
Щелкните на строке меню Выход
и вставьте в заготовку процедуры обработчика
текст так, чтобы она приняла вид рис. 13.
procedure
TfMain.mmCloseClick(Sender: TObject);
// закрытие формы и приложения
begin
fMain.Close;
end; |
Рис. 13.
Процедура закрытия приложения
Щелчок по этой строке меню
приведет к закрытию приложения.
9.2.
Освобождение памяти
Пользователь может
закрыть приложение, щелкнув по строке Выход
или по крестику в правом углу окна. В обоих
случаях необходимо выполнить операции, которые
освободят память, занятую динамическими
массивами a и u. Для
этого нужно запрограммировать событие OnClose
(на закрытие) для формы fMain, которое
возникает при зыкрытии этой формы.
1. Щелкните по форме и убедитесь, что ее атрибуты
появились в окне Object Inspector.
2. На закладке Events (события) дважды
щелкните по значению события OnClose.
3. Вставьте в заготовку процедуры обработчика
текст так, чтобы она приняла вид рис. 14.
procedure
TfMain.FormClose(Sender: TObject; var Action: TCloseAction);
// освобождение памяти, занятой динамическими
массивами
begin
a:= Nil;
u:= Nil;
end; |
Рис. 14.
Процедура освобождения памяти
Теперь приложение
полностью запрограммировано и готово к
эксплуатации.
|