Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Основы программирования в Delphi. Учебно-методическое пособие
.pdf
Основы программирования в Delphi
for i:=1 to 5 do
for j:=1 to 5 do
a[i,j]:=StrToInt(StringGrid1.Cells[j-1,i-1]);
S:=0;
for i:=1 to 5 do
for j:=1 to 5 do
S:=S+abs(a[i,j]);
Label2.Caption:= 'Сумма модулей элементов массива: ' + IntToStr(S);
end;
Пример. Дана матрица размера n * m. Получить последовательность b1, ..., bn,
где b
- это сумма наибольшего и наименьшего из значений элементов k - ой
k
строки (рис. 6.3).
Рис. 6.3 Нахождение суммы минимального и максимального
элементов каждой строки
Программный код кнопки Вычислить выглядит следующим образом:
procedure TForm1.Button1Click(Sender: TObject);
var A: array[1..4, 1..5] of real;
min, max: array [1..4] of real;
i, j: integer;
begin
for i:=1 to 4 do // Передвижение по строкам
for j:=1 to 5 do // Считывание элементов строк из StringGrid1
51

Основы программирования в Delphi
begin
if Length(StringGrid1.Cells[j-1,i-1]) <>0
then a[i, j] := StrToInt(StringGrid1.Cells[j-1, i-1] )
else a[i, j]:=0; // Если ничего не введено, то принимаем за ноль
end;
// Вычисление максимума и минимума строки
for i:=1 to 4 do
begin
min[i] := a[i,1];
max[i] := a[i,1];
for j:=2 to 5 do
begin
if a[i,j] < min[i] then min[i] := a[i,j];
if a[i,j] > max[i] then max[i] := a[i,j];
end;
end;
// Вывод суммы минимума и максимума в StringGrid2
for i:=1 to 4 do
StringGrid2.Cells[0,i-1]:= FloatToStr(min[i])+ ' + '+
FloatToStr(max[i])+ ' = '+
FloatToStr(min[i]+max[i]);
end;
Кроме того для предотвращения неправильного ввода в ячейки StringGrid
используем следущий код:
procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
begin
case Key of
#8, '-', '0'..'9': ; // цифры , <Back Space> и '-' остаются без изменений
#13:// <Enter> - если возможно, то переход на следующую ячейку
if StringGrid1.Col < StringGrid1.ColCount - 1
then StringGrid1.Col := StringGrid1.Col + 1;
'.',',': Key := DecimalSeparator;
else key := Char(0); // остальные символы
end; //end of case
end;
52

Основы программирования в Delphi
6.4 Инициализация массивов-констант
При отладке программ на логические ошибки ввод значений элементов
массива с клавиатуры занимает много времени. Чтобы пройти этот этап быст-
рее, значения элементов массива следует определять в коде программы. Для
этого следует объявить массив как константу и инициализировать элементы
массива одним выражением. Например:
const
A1: array [1 .. 5] of real= (3, 2.7, 6.1, 30.5, 0.2);
Если измерений у массива более одного, то измерения вкладываются друг
в друга, начиная с младших строк. Например:
const
A2: array [1 .. 3, 1 .. 5 ] of integer = (( 3, 2, 6, 30, 2 ),
(67, 30, 10, 5, 15 ),
(5, 40, 27, 42, 17));
Здесь каждая строка массива начинается с новой строки. Расположение
элементов массива, таким образом, хотя и необязательно, но очень наглядно.
6.5 Динамические массивы
Обычно диапазоны изменения массива неизменны и поэтому должны опи-
сываться явно с помощью констант, задающих нижнюю и верхнюю границы
диапазона. Такие массивы называются статическими. Pascal позволяет определять также динамические массивы, размер которых заранее неизвестен и
может меняться во время работы программы. Для описания динамических мас-
сивов указывать диапазоны значений его измерений не нужно. Например:
var
DynArray: array of integer;
Первоначально в переменной, описанной как динамический массив, нет ни
одного элемента. Ее размер задается с помощью стандартной процедуры
SetLength( ). В качестве первого параметра указывается имя переменной, в качестве второго – число элементов в массиве.
Если новое число элементов больше старого, то новые элементы добавляются в конец массива, а их значения исходно будут неопределены. Если новое число элементов меньше старого, то последние элементы массива отбрасы-
53

Основы программирования в Delphi
ваются и теряются. Отсчет элементов динамического массива всегда начинает-
ся с нуля.
var
DynArray: array of integer;
begin
SetLength (DynArray, 9); // динамический массив из 10-и элементов
DynArray [ 0 ]:= 2;
Чтобы освободить память, выделенную динамическому массиву, и сделать
его длину нулевой, надо соответствующей переменной присвоить значение nil:
DynArray := nil;
После этого в массиве DynArray не окажется ни одного значения. В даль-
нейшем длину массива DynArray можно изменить снова.
Как и статические массивы, динамические массивы могут иметь несколько
измерений. Для каждого из измерений при описании массива надо повторять
описание array of. Например, если требуется объявить динамический массив
целых чисел с двумя измерениями, надо записать так:
var
DArray2: array of array of integer;
Далее надо объявить размер этого массива по каждому измерению. Реали-
зация динамических массивов в Pascal позволяет, в отличие от описания стати-
ческих массивов, задавать разные диапазоны для одного измерения. Например,
когда описан двумерный массив, сначала задается размер по первому измере-
нию (число столбцов):
var
DArray2: array of array of integer;
begin
SetLength (Darray2, 4);
Далее нужно указать число элементов для каждого из четырех столбцов.
Длина соответствующего столбца задается указанием имени массива с номером
столбца с помощью процедуры SetLength():
SetLength (Darray2[ 0 ], 4);
SetLength (Darray2[ 1 ], 7);
SetLength (Darray2[ 2 ], 30);
SetLength (Darray2[ 3 ], 1);
54

Основы программирования в Delphi
6.6 Сортировка массивов
Сортировка массива – это перегруппировка его элементов, приводящая к
их упорядоченному расположению. Цель сортировки является облегчение последующего поиска элементов массива. Существуют различные алгоритмы и
методы сортировки массивов. Метод сортировки массива называется устойчивым, если в процессе перегруппировки относительное расположение элементов
с равными ключами не изменяется. Основным условием при сортировке массивов является отсутствие дополнительных массивов, то есть все перестановки
элементов должны выполняться на том же месте в исходном массиве.
Среди простых методов сортировки массивов известны:
1) метод прямого обмена (пузырьковая сортировка);
2) метод прямого выбора;
3) сортировка с помощью прямого включения;
4) шейкерная сортировка.
К улучшенным методам сортировки массивов можно отнести следующие:
1) метод Шелла, усовершенствование метода прямого включения;
2) сортировка с помощью дерева, метод HeapSort, Д. Уильямсон;
3) сортировка с помощью разделения, метод QuickSort, Ч. Хоар. Это улучшен-
ная версия пузырьковой сортировки.
Метод пузырька
В пузырьковой сортировке последовательно сравниваются два соседних
элемента массива. Если они расположены в неправильной последовательности,
то выполняется перестановка этих элементов массива местами. Сортировка
осуществляется путем многократного прохождения по списку элементов массива. При сортировке по возрастанию элементы с малыми значениями поднимаются вверх, то есть в начало списка, подобно пузырьку воздуха в стакане воды, поэтому метод и получил такое название.
Реализация пузырьковой сортировки в Delphi имеет вид:
type vec = array[1..50] of extended;
ind = array[1..50] of integer;
Procedure PSort(var a:vec; n:integer);
var k,kol:integer;
w:extended;
p:boolean;
55

Основы программирования в Delphi
begin
kol:=1;
repeat
p:=true;
for k:=1 to n-kol do
if a[k]>a[k+1] then
begin
w:=a[k];
a[k]:=a[k+1];
a[k+1]:=w;
p:=false;
end;
inc(kol);
until p;
end;
В общем случае для сортировки массива в данном случае требуется n-1
проход по массиву. Чтобы исключить ненужные проходы, если массив уже
полностью или частично отсортирован, используется не цикл с заданным количеством повторений (for kol:= 1 to n-1 do), а оператор repeat с флажком p.
Метод прямого выбора
Сортировка осуществляется путем многократного прохождения по списку
элементов. На каждом (k-ом) проходе находится минимальный элемент с k-го
по n-ый элементы, который затем переставляется с k-ым элементом.
Реализация этой сортировки в Delphi имеет вид:
Procedure PrSort(var a:vec; n:integer);
var k,i,m:integer;
w:extended;
begin
for k:=1 to n-1 do
begin
m:=k;
for i:=k+1 to n do
if a[i]<a[m] then m:=i;
w:=a[m]; a[m]:=a[k]; a[k]:=w;
end;
56

Основы программирования в Delphi
end;
Метод Шелла
Алгоритм Шелла намного эффективнее, чем, например, метод пузырька. В
данном алгоитме сначала сравниваются отдаленные, а затем близкорасполо-
женные элементы массива. Переменная kol содержит интервал, разделяющий
сравниваемые элементы массива. Начальное значение этой переменной равно
половине количества элементов массива. В процессе сортировки значение переменной kol уменьшается в два раза на каждом проходе, пока не начнет выполняться сравнение соседних элементов, как в методе пузырька.
Реализация сортировки Шелла в языке Delphi имеет вид:
Procedure ShSort(var a:vec; n:integer);
var k,kol:integer;
w:extended;
p:boolean;
begin
kol:=n div 2;
repeat
repeat
p:=true;
for k:=1 to n-kol do
if a[k]>a[k+kol] then
begin
w:=a[k];
a[k]:=a[k+kol];
a[k+kol]:=w;
p:=false;
end;
until p;
kol:=kol div 2;
until kol=0;
end;
Примечание. Перестановка элементов со сложными типами данных яв-
ляется довольно длительным процессом. Поэтому рекомендуется вместо пе-
рестановки самих данных переставить их индексы. Такой прием используется
57

Основы программирования в Delphi
практически во всех коммерческих программах. В этом случае процедура сортировки Шелла имеет следующий вид:
type ind=array[1..50] of integer;
Procedure ShSortInd(a:vec; n:integer; var nom:ind);
var k,kol,w:integer;
p:boolean;
begin
for k:=1 to n do nom[k]:=k;
kol:=n div 2;
repeat
repeat
p:=true;
for k:=1 to n-kol do
if a[nom[k]]>a[nom[k+kol]] then
begin
w:=nom[k];
nom[k]:=nom[k+kol];
nom[k+kol]:=w;
p:=false;
end;
until p;
kol:=kol div 2;
until kol=0;
end;
Метод Хоара
В алгоритме сортировки Хоара сначала выбирается опорное значение. Затем элементы со значением, меньше опорного элемента, переносятся влево, а со
значением, большим или равным ему переносятся вправо. Таким образом, на
первом шаге алгоритм Хоара делит элементы на два раздела: со значениями,
меньшими опорного, и со значениями, большими или равными ему. Затем под-
программа, рекурсивно вызывая сама себя, продолжает разбивку разделов. В
каждом разделе выбирается новое опорное значение, и элементы раздела пере-
ставляются влево и вправо. Процесс разбивки на разделы рекурсивно продолжается до тех пор, пока размер раздела достигнет одного или двух элементов.
Эффективность данного алгоритма сортировки зависит от объема данных и вы-
58

Основы программирования в Delphi
бора метода опорного сечения. В приведенном ниже алгоритме в качестве
опорного элемента выбирается средний элемент раздела.
Реализация сортировки Хоара на языке Delphi имеет вид:
Procedure QSort(var a:vec; low,high:integer);
var l,r:integer;
op,w:extended;
begin
op:=a[(low+high) div 2];
l:=low; r:=high;
repeat
while (l<=high) and (a[l]<op) do inc(l);
while (r>=low) and (a[r >op) do dec(r);
if l<=r then
begin
w:=a[l]; a[l]:=a[r]; a[r]:=w;
inc(l); dec(r);
end;
until l>r;
if r>low then QuickSort(a,low,r);
if l<high then QuickSort(a,l,high);
end;
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Как объявляется одномерный массив в Delphi?
2. Основные свойства компонента StringGrid?
3. Каким образом создаются многомерные массивы в Delphi?
4. В чем особенность динамических массивов?
5. Перечислите основные методы (алгоритмы) сортировки массивов.
6. Как работает метод пузырьковой сортировки?
7. В чем особенность метода сортировки Хоара?
ВИДЕО-УРОК 5
https://youtu.be/A23G4B2jZzk
59

Основы программирования в Delphi
7. ПОНЯТИЕ ИСКЛЮЧИТЕЛЬНОЙ СИТУАЦИИ
Под исключительной ситуацией в программе понимается состояние программы, возникающее при выполнении некоторых действий. Например, это
может быть деление на ноль, попытка открыть несуществующий файл на диске,
выход индекса элемента массива за пределы допустимого и т.д. В этом случае
требуется выполнить определенные операции для продолжения ее работы или
корректного завершения.
При работе в среде разработки Delphi возникновение одной из вышеназванных или других подобных ситуаций обычно приводит к полной остановке
выполнения программы. Каждая подобная ситуация имеет свое название и тип.
Для повышения надежности программы и защиты ее от преждевременного завершения в Delphi предоставлена возможность с помощью определенных опе-
раторов перехватить различные исключительные ситуации и организовать вы-
полнение определенных операций при их возникновении. При отладке программы, использующей обработку исключительных ситуаций предварительно
необходимо отменить стандартную реакцию среды Delphi на эти ситуации. Для
этого надо в главном меню Delphi необходимо отключить опцию Stop on Delphi
Exceptions находящуюся в Tools Debbuger Options на закладке Language Exceptions.
Для перехвата исключительных ситуаций и описания реакций на их воз-
никновение в Delphi предусмотрены операторы организации защищенного блока try ... end двух видов:
...
try //попытаться выполнить
<последовательность защищенных операторов>
except //обработчики исключительных ситуаций:
on <тип искл. ситуации 1> do <оператор–обработчик 1>;
...
on <тип искл. ситуации k> do <оператор–обработчик k>;
else //может отсутствовать
<операторы выполняемые если перехваченная ситуация не обнаружена
среди типов ситуаций 1†k>
end;
<следующий оператор>;
...
60
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
