logo search
Программирование в среде Delphy / Программирование в среде Delphi

8. Работа с массивами

Массив – это пронумерованный набор однотипных данных. Тип массива определяется в разделе типов и в общем случае имеет вид

Type имя массива=Array[список индексов и диапазоны их изменения] of тип элемента массива;

Пример объявления массивов:

Type Ta=array[1..10] of integer;

Tb=array[1..5,1..10] of extended;

Var a:Ta; b:Tb;

…………………

a[1]:=25; b[5,10]:=-1.5;

Здесь объявлены: одномерный массив a целого типа, в котором элементы пронумерованы от 1 до 10, и двухмерный массив b вещественного типа, в котором первый индекс может изменяться в пределах от 1 до 5, а второй индекс – от 1 до 10. Индексы для элементов массивов могут быть любыми выражениями целого типа.

Рассмотрим пример написания обработчика нажатия какой–либо кнопки на форме, в котором произведем умножение матрицы A на вектор . В матричной форме это выглядит так:

или или ,

где n – размерность квадратной матрицы A и векторов Y и X.

Для визуализации массивов будем использовать табличные компоненты StringGrid1 для матрицы A, StringGrid2 для вектора X и StringGrid3 для вектора Y. Тогда обработчик события нажатия какой–либо кнопки будет выглядеть следующим образом:

// Обработчик нажатия кнопки

Procedure TForm1.Button1Click(Sender: TObject);

Const Nmax=10; // Максимальная размерность массивов

Type Ta=array[1..Nmax,1..Nmax] of extended;

Txy=array[1..Nmax] of extended;

Var A:Ta; x,y:Txy;n,I,j:integer;

Begin

n:=StrtoInt(Edit1.Text); // Определение текущей размерности массивов

Randomize; // Инициализация датчика случайных чисел

with StringGrid1 do Begin // Подготовка визуальных компонентов

ColCount:=n+1;

RowCount:=n+1;

FixedCols:=1;

FixedRows:=1;

Sells[0,0]:=’A’;

End;

with StringGrid2 do Begin

ColCount:=2;

RowCount:=n+1;

FixedCols:=1;

FixedRows:=0;

Sells[0,0,]:=’X’;

End;

with StringGrid3 do Begin

ColCount:=2;

RowCount:=n+1;

FixedCols:=1;

FixedRows:=0;

Sells[0,0]:=’Y’;

End;

For i:=1 to n do Begin // Заполнение массивов случайными числами

StringGrid1[0,i]:=Inttostr(i);

StringGrid1[i,0]:=Inttostr(i);

StringGrid2[0,i]:=Inttostr(i);

StringGrid3[0,i]:=Inttostr(i);

For j:=1 to n do

A[i,j]:=random;

StringGrid1.Cells[j,i]:=Floattostr(a[i,j]);

X[i]:=ramdom;

StringGrid2.Cells[1,i]:=Floattostr(x[i]);

End;

For i:=1 to n do Begin // Вычисление произведения матрицы на вектор

Y[i]:=0;

For j:=1 to n do

Y[i]:=y[i]+a[i,j]*x[j];

End;

For i:=1 to n do // Заполнение значениями компонента StringGrid3

StringGrid3.Cells[1,i]:=FloattoStr(y[i]);

End;

Рассмотрим теперь задачу сортировки элементов одномерного целого массива в порядке возрастания их значений методом «пузырька», когда можно менять местами только два соседних элемента массива. Размерность массива будет у нас задаваться в компоненте Edit1, начальный массив – в компоненте StringGrid1, а результат сортировки – в компоненте StringGrid2. Обработчик нажатия какой–либо кнопки будут иметь следующий вид:

// Обработчик нажатия кнопки

Procedure TForm1.Button1Click(Sender: TObject);

Const Nmax:=20; // Максимальная размерность массива

Type Ta=array[1..nmax] of integer; // Тип Массива

Var a:Ta; i,j,k,n:integer; // Внутренние переменные

Begin

n:=StrtoInt(Edit1.Text); // Определение размерности массива

StringGrid1.ColCount:=1; // Подготовка визуальных компонентов

StringGrid1.RowCount:=n;

StringGrid2.ColCount:=1;

StringGrid2.RowCount:=n;

Randomize; // Инициализация датчика случайных чисел

// Заполнение начального массива случайными числами

For i:=1 to n do Begin

a[i]:= Random(2*n);

StringGrid1.Cells[0,i-1]:=InttoStr(a[i]);

End;

Repeat // Начало сортировки массива a

J:=0; // Зануление индикатора наличия перестановок

For i:=1 to n-1 do // Проход по всем элементам массива

If a[i]>a[i+1] then Begin

k:=a[i]; // Перестановка двух соседних элементов массива

a[i]:=a[i+1];

a[i+1]:=k;

j:=j+1;

end;

until j<=0; // Проверка наличия перестановок

For i:=1 to n do StringGrid2.Cells[0,i-1]:=inttostr(a[i]); // Вывод результата

End;

Решим теперь эту же задачу, но методом последовательного поиска минимального элемента. Сначала определим среди всех элементов массива минимальный и поменяем его местами с первым. Затем найдем минимальный, начиная со второго элемента, и поменяем найденный минимальный элемент уже со вторым и т.д. Запишем только алгоритм этой сортировки:

For i:=1 to n-1 do Begin // Начало сортировки

j:=a[i]; jmax:=i; // В качестве начального минимального берем i–й эл.

For k:=i+1 to n do // Проходим по всем остальным элементам массива

If j>a[k] then Begin // Сравниваем текущий с запомненным

j:=a[k]; jmax:=k; // Запоминаем новый минимальный элемент

end;

if jmax<>i then Begin

// Если нашли минимальный, то меняем его местами с i–м

a[jmax]:=a[i];

a[i]:=j;

end;

end;

Можно описывать и так называемые динамические массивы без указания диапазона значений индексов, например:

Var A:array of integer;

B:array of array of Byte;

Фактически это означает, что переменные A и B являются указателями на пока еще не выделенную область памяти. Выделение памяти под эти массивы должно происходить на этапе выполнения программой SetLength. В нашем случае это можно сделать, например, так:

SetLength(A, 10);

SetLength(B, 2);

SetLength(B[0],5);

SetLength(B[1],20);

Здесь массиву А выделяется память на 10 элементов массива, причем значение индекса начинается с нуля. Массиву B выделяется память под две строки, в первой строке может быть 5 элементов, а во второй строке 20 элементов.

Освобождение памяти производится процедурой Finalize или присвоением константы Nil, например:

Finalize(A);

B:=Nil;