Вернуться назад

Программирование.
Часть 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. Процедура освобождения памяти

Теперь приложение полностью запрограммировано и готово к эксплуатации.

 

</body> </html>