Обработка одномерных массивов в Delphi

advertisement
Обработка одномерных массивов
В процессе решения экономических задач на ЭВМ часто приходится
сталкиваться с такими, в которых выполняются не только вычислительные
операции, но производится обработка больших объемов данных, имеющих
достаточно сложную структуру. Обычно в таких задачах выполняются
следующие действия:
 ввод и хранение больших наборов данных;
 поиск записей, удовлетворяющих определенному условию (лог ические
операции над данными);
 выполнение различных вычислительных действий (поиск минимальных,
максимальных и средних значений, определение заданных сумм или
произведений, вычисления по формулам);
 формирование из них новых наборов данных;
 вывод данных на внешние носители (на принтер, в файл и т.п.).
В связи с этим важно уметь обрабатывать подобные наборы данных,
которые называются массивами данных.
Массивом называется совокупность однородных элементов,
характеризующихся одинаковыми признаками (например, массив целых чисел,
массив вещественных чисел, массив однородных записей и т.п.), т.е. все
элементы массива должны бы одного типа. Массив характеризуется своим
именем, типом хранимых элементов, размерностью (числом хранимых
элементов). Кроме того для массива характерна позиционность его элементов,
т.е. каждое элементу массива соответствует определенный н омер его позиции в
общем списке данных, называемый индексом, позволяющим выбрать из массива
определенный элемент. Например, массив с именем А содержит n однотипных
элементов, тогда обозначение одного элемента будет иметь вид А i , где i —
индекс элемента массива, принимающий значение в диапазоне от I до n, где
i={l, 2,3 ...n}, а n — это размерность массива т.е. число элементов в нем.
В простейшем случае элементами массива являются переменные,
принимающие числовые или символьные значения.
Одномерный числовой массив X = (X 1 , Х 2 , ...,Х n } состоит из n элементов,
каждый из которых число целое или вещественное.
Символьные переменные записываются в апострофах, поэтому мас сив
символов X имеет вид: для n=4, X 1 ='S’, Х 2 = 'R', Х 3 = '6', Х 4 ='#'
Массив может иметь сложную структуру, когда каждый элемент представляет
собой запись — т.е. совокупность логически связанных данных.
Например, экзаменационная ведомость включает данные о фамилии, оценке,
подписи преподавателя, т.е. для этой задачи имеем массив данных, элемент ом
которого является запись, содержащая информацию о каждом студенте, а
именно: номер по порядку, Ф.И.О., номер зачетной книжки, оценка цифрой,
оценка прописью, подпись преподавателя.
Так как программирование в системе Delphi предполагает сначала разработку
1
формы, а далее — создание обработчика событий с использованием средств
Delphi и языка Object Pascal для выполнения нужных действий, то рассмотрим
возможности этих систем для решения основных этапов обработки массивов.
Для ввода и вывода элементов массива на форме необходимо разместить
компоненты Delphi в которых будут пользователем введены размерности
массивов ( количество элементов) и сами элементы массивов, а так же
компоненты для вывода результатов обработки массивов.
Для ввода размерности массивов наиболее часто используются компоненты
Edit и SpinEdit, а для ввода элементов массива компоненты Edit, Memo,
ListBox.
Для вывода результатов обработки массивов используются компоненты Edit,
Memo, StaticText, Label, ListBox .
Ввод или выбор размерности массива
А) Ввод размерности
Ввод размерности одномерного массива можно выполнить с ис пользованием
компонента Edit. Так как данные, вводимые в свойство Text редактора F.dit,
имеют строковый тип, то для получения численного значения размерности
необходимо выполнить - преобразование строковой переменной в
целочисленную с помощью функции преобразования StrToInt().
Пример.
Выполнить ввод размерности n одномерного массива А, где n <=20, в поле
компонента Edit с контролем вводимого числа.
Разместим на форме метку Label1— для поясняющих надписей, редактор
Edit1 — для строки ввода, кнопку Button1 — для выполнения события OnClick
для ввода размерности в переменную «n».
Зададим следующие свойства компонентам:
Label1
Edit1
Label1
Editl
Caption = Введите размерность
Text = Очистить поле ввода
Buitton1 Caption = Размерность
Button1
В этом случае процедура, реализующая ввод размерности, т.е. об работчик
события нажатия на кнопку, имеет вид:
2
procedure TForml.Button1Click (Sender:TObject);
begin
if Edit1.Text = ' ' //если в строке ввода пусто
then ShowMessage ('Введите размерность массива А, n <=20')
else begin
n:= StrToInt (EditI.Text);
if (n<2) or (n>20) ..//если «n» введен неверно
then begin
Edit1 .Text := ' ';
ShowMessage ('Введите правильную размерность');
end
else begin
Button1.Visible := False;
Label 1. Caption := 'Ввод размерности корректен';
end;
end;
end;
В приведенном примере используется стандартная функция ShowMessage,
отображающая окно сообщения с кнопкой ОК.- Па это сообщение необходимо
дать ответ «да» или «нет». Текст сообщения записывается в апострофах.
Б) Выбор размерности
Выбор размерности одномерного массива можно выполнить, используя
компонент кнопку-счетчик с окном редактирования SpinEdit (страница Samples)
— редактор для ввода целого числа .
Компонент SpinEdit (страница Samples палитры компонентов) предназначен
для ввода или отображения целого числа и представляет собой комбинацию
однострочного редактора и кнопок. Редактор может вводить только числа, а
кнопки позволяют изменять числа на некоторую фиксированную величину.
Основные свойства компонента:
Text — содержит вводимый или выводимый текст.
MaxValue — верхняя граница диапазона возможных значений Value.
MinValue — нижняя граница диапазона возможных значений Value.
Value — текущее значение числовой величины (тип Integer).
Increment — фиксированная величина шага изменения числа.
Событием по умолчанию является событие OnChange, которое вызывается
двойным щелчком ЛКМ по выделенному компоненту SpinEdit. При этом в окне
кода появляется шаблон обработчика событий, где записывается команда
присвоения переменной n выбранное значение размерности.
3
procedure TForml.SpinEditlChange (Sender:TObject);
begin
n := SpinEdit1.Value;
end;
Если при создании стартовой формы были определены значения св ойств
MaxValue и MinValue и значение выбирается с помощью кнопок увеличения или
уменьшения, то можно не выполнять контроль вводи мого числа.
Организация ввода элементов одномерного массива
1. Объявление переменной как одномерного массива
Все объекты программы должны быть объявлены в модуле, их использующем.
Объявление может быть глобальным или локальным.
Глобальное объявление помещают в разделе Interface модуля в соответствующих
разделах Const, Type, Var. Переменные, объявленные как глобальные доступны для
обработки любым обработчиком события данного модуля.
Локальное объявление помещается в соответствующий раздел в описательной части
конкретного обработчика события или пользовательской процедуры (функции) и
описанные таким образом переменные доступны только внутри данного обработчика
события, процедуры или функции.
Описание одномерного массива в разделе переменных VAR
Формат описания одномерного массива в разделе переменных.
Var <имя массива>: Array [<тип-диапазон>] Of<тип элементов>;
Тип диапазон – это подмножество своего базового типа, задается границами
значений внутри базового типа, т.е. границами:
<минимальное значение>…<максимальное значение>
Пример:
Const N = 10; // задается равномерность массива
Var X : Array [1 .. N] Of Real; // описание массива
4
Организация вывода элементов одномерного массива
A) вывод в компонент Edit:
For I := 1 to М do
Edit 1 .Text:=Edit 1 .Text + ' ' + lntToStr(A[I]);
Б) вывод в компонент Memo:
В строку:
For I := 1 to M do
Memol.Text:=Mcmol.Tcxt + '' + IntToStr (A[I]);
// использование свойства Text компонента Memo
В столбик:
For I :== 1 to M do
//использование метода Add — добавление новой строки в список
Memol. Lines.Add (IntToStr (A[I]));
В) вывод в компонент Label:
For 1 :=- 1 to М do
Label 1 .Caption := Labell.Caption -(-IntToStr(A[I]) + ' ';
Г) вывод в компонент StaticText:
For I := 1 to M do
StaticText1.Caption := StaticText1.Caption + IntToStr(A[I]) + ' ';
Д) вывод в компонент ListBox:
For 1 := 0 to M-l do
ListBoxl.Items.add (IntToStr(A[i]));
Примеры ввода-вывода и обработки элементов одномерных массивов с использованием
компонент Edit, Memo, Label, StaticText подробно рассмотрены в учебных пособиях
[1,2,3]. В данных методических материалах рассматривается использование компонента
ListBox для ввода и вывода элементов одномерных массивов.
Компонент ListBox (страница Standard)
Компонент класса TListBox представляет собой стандартный для Windows
список выбора, с помощью которого можно выбрать один или несколько
элементов. Компонент позволяет отображать на экране список строк,
произвольных изображений, которые выбираются щелчком мыши. Основные
5
свойства представлены ниже:
BorderStyle — определяет стиль рамки.
Canvas — канва для программной прорисовки элементов.
Columns — определяет количество колонок элементов в списке.
Count — содержит количество строк в компоненте.
Itemlndex — определяет индекс выделенного элемента в списке.
Нумерация начинается с нуля. Если выделенного элемента нет, то возвращается
(-1). Если выделено несколько элементов, то возвращается индекс активного
выделенного элемента. Свойство доступно только на этапе выполнения
программы.
Items — содержит набор строк, показываемых в компоненте.
MultiSelect — разрешает или запрещает выбор нескольких элементов (True
— такое выделение возможно. False — можно выделить только один элемент).
Selected(X) — содержит признак выбора для элемента с индексом X.
Если Х-ый элемент списка выделен, то Sclcctcd(X) = True, в противном случае —
False. Свойство доступно только на этапе выполнения программы.
Sorted — разрешает или отменяет сортировку строк по алфавиту.
Для создания списка в программе используются методы свойства Items:
Add(S) — добавить строку S и вернуть ее индекс,
Append (S) — добавить строку S без возврата ее индекса,
Insert (Index, S) — вставляет в список строку S и присваивает ей индекс
Index (Index — целое число).
Для удаления всех элементов списка используется метод Clear, например,
ListBoxl.Clear.
Событием по умолчанию является событие OnClick.
Пример. Допустим, на форме размещен компонент Editl, с помощью
которого будет вводиться элемент списка. Для того чтобы поме стить этот
элемент в список ListBoxl, следует выполнить команду:
ListBox I.Items. Add (Editl .Text)
Примеры ввода-вывода и обработки элементов массивов с использованием
компонент Edit, Memo, Label, StaticText подробно рассмотрены в учебных
пособиях [ 1, 2,3]. В данных методических материалах рассматривается
использование компонента ListBox для ввода и вывода элементов одномерных
массивов.
Обработка элементов одномерного массива с использованием компонента ListBox
Компонент ListBox используют для создания списков, представляющих собой
упорядоченный набор строк, которые являются описанием некоторых однородных
элементов. В частности, список можно рассматривать как одномерный массив строк.
В зависимости от характера решаемой задачи могут использоваться простые и
комбинированные списки, центральным свойством которых является свойство Items
6
типа TString. С помощью него можно управлять структурой списка и обращаться к
любому из его элементов.
Рассмотрим использование компонента ListBox для создания и обработки простых
списков, которые представляют собой оконный элемент управления, предназначенный
для отображения большого количества строк списка в прямоугольной области
компонента. Если размера прямоугольной области компонента не хватает, чтобы
отобразить все его элементы, то с правой стороны автоматически добавляется полоса
прокрутки. Количество строк в поле компонента ListBox фиксируются в свойстве
Count, значения которого можно использовать в программе обработки элементов
списка, рассматриваемых как элементы одномерного массива.
В связи с тем, что значение свойства Count определяет количество элементов
одномерного массива в поле компонента ListBox, на форме нет необходимости создавать
компонент для ввода размерности массива.
По умолчанию строки в списке отображаются в порядке их добавления, при этом
первая строка получает значение 0, а последняя Count — 1.
Компонент ListBox представляет множество различных свойств и методов для
выбора элементов из списка и выполнения определенных действий над выбранным
элементом. Обращаться к элементу списка можно с помощью свойства ItemIndex.
Список может быть сформирован во время создания формы приложения и во время
работы программы. Для формирования списка во время создания формы необходимо
выделить компонент ListBox и в окне Object Inspector, на странице Events, выбрать
свойство Items и затем щелкнуть на кнопке …
Для создания списка во время работы
программы надо написать обработчик событий формирования списка (элементов
одномерного массива) в поле компонента ListBox.
В данных методических материалах рассмотрен вариант создания списка с
использованием компонента ListBox и последующей обработки элементов списка и
вывода результатов в процессе выполнения программы.
Пример программного приложения обработки одномерного массива с
использованием компонента ListBox
Задание
Даны два одномерных массива: А, содержащий m элементов целого типа, и B,
содержащий n элементов целого типа. Сформировать массив С из элементов массива А
несовпадающих по своему значению с элементами массива В. В массиве С найти
максимальный элемент и его номер. Поиск максимального элемента в одномерном
массиве оформить как подпрограмму.
Стартовая форма программного приложения представлена на рис. 1.
На стартовой форме размещены следующие компоненты:
На компоненте Panel1 размещен компонент StaticText1.
На компоненте Panel2 размещены следующие компоненты: Label1, Label2, Label3,
Label4, Edit1, Edit2, Вutton1, Button2, ListBox1, ListBox2.
7
На компоненте Panel3 размещены следующие компоненты: StaticText2, ListBox3,
StaticText3, StaticText4, Edit3.
На компоненте Panel4 размещены следующие компоненты: BitBtn, Вutton3,
Вutton4.
На компоненте Panel5 размещен компонент Memo1.
Рис. 1 Стартовая форма программного приложения
8
Текст программного модуля формирования одномерного массива С:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ExtCtrls;
type
TForm1 = class (TForm)
Panel1: TPanel;
StaticText1: TStaticText;
Panel2: TPanel;
Label1: TLable;
Label2: TLable;
Label3: TLable;
Labe14: TLable;
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Button2: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
Panel3: TPanel;
StaticText2: TStaticText;
ListBox3: TListBox;
StaticText3: TStaticText;
StaticText4: TStaticText;
Edit3: TEdit;
Panel4: TPanel;
BitBtn1: TBitButn;
Button3: TButton;
Button4: TButton;
Panel5: TPanel;
Memo1: TMemo;
procedure Button1Click (Sender: TObject);
procedure Button2Click (Sender: TObject);
procedure Button3Click (Sender: TObject);
procedure Button4Click (Sender: TObject);
private { Private declarations}
public { Public declarations}
end;
const q:=100;
type tm=array[1..q] of real;
9
var
Form1: TForm;
A, B, C: tm; // A, B, C – массивы
l, m, n, i, j: integer;
Cmax: real; // значение максимального элемента массива С.
cx: integer; // номер максимального элемента массива С.
implementation
{$R* . dfm}
{Пользовательская процедура PMAX поиска максимального элемента и его номера в
одномерном массиве}
procedure PMAX (C: array of real; d: integer; var max: real; var p: integer);
var k: integer;
begin
max:=C[1];
p:=1;
for k:=1 to d do
if (max<C[k] )
then begin
max:=C[k];
p:=k;
end;
end;
{Обработчик события ввода элементов массива А в ListBox1, активизируется при
нажатии на кнопку «Ввод-А»}
procedure TForm1.Button1Click(Sender: TObject);
begin
if (edit1.text<>’’) // проверка корректности ввода
then begin
ListBox1.Items.add(edit1.Text);
edit 1.Clear;
edit1.setfocus;
end;
else showmessage (‘Строка ввода пуста’)
end;
10
{Обработчик событий ввода элементов массива в ListBox2, активизируется при
щелчке на кнопку «Ввод-В»}
procedure TForm1.Button2Click(Sender: TObject);
begin
if (edit2.Text<>' ') // проверка корректности ввода
then begin
ListBox2.Items.add(edit2.Text);
edit 2.Clear;
edit2.setfocus;
end;
else showmessage('Строка ввода пуста')
end;
{Обработчик событий формирования массива С, активизируется при щелчке на
кнопку «Сформировать массив С»}
procedure TForm1.Button3Click(Sender: TObject);
var element: boolean;
begin
l:=1; //индекс элемента массива C
m:=listBox1.Items.count; // количество элементов массива А
n:=listBox2.Items.count; //количество элементов массива В
{формирование числового массива А из данных, введенных в ListBox1}
for i:=1 to m do
A[i]:=strtofloat(listbox1.Items[i-1]);
{формирование числового массива В из данных, введенных в ListBox2}
for j:=1 to n do
B[j]:=strtofloat(listbox2.Items[j-1]);
// формируем массив С
for i:=0 to m-1 do
begin
element:=false;
for j:=0 to length(b)-1 do
if(A[i]=B[j])
then element:=true;
if (element=false)
then begin
С[l]:=A[i];
listBox3.Items.add(floattostr (C[l]));
l:=l+1;
end;
11
// вызов пользовательской процедуры поиска максимума
Pmax(C, l -1, Cmax, cx);
Edit3. text :=floattostr(Cmax)+', под номером ' +inttostr(cx);
end;
end;
{Обработчик событий очистки полей ввода–вывода данных, активизируется при
нажатии на кнопку «Очистить»}
procedure TForm1.Button4Click(Sender: TObject);
begin
listbox1.Items.Clear;
listbox2.Items.Clear;
listbox3.Items.Clear;
edit1.clear;
edit1.SetFocus;
edit2.clear;
edit2.SetFocus;
edit3.clear;
end;
end.
При возникновении ошибки в процессе выполнения программы на форму выводится
окошко с сообщением о ней.
Форма с окном сообщения об ошибке представлена на рис. 2
Риc.2 Форма с сообщением об ошибке ввода
12
Форма с результатами решения задачи представлена на рис. 3
Рис. 3 Форма с результатами решения задач
Динамический массив
Обычно размеры массива неизменны и поэтому должны объявляться явно с
помощью констант, задающих нижнюю и верхнюю границу диапазона, определяющего
максимальное количество элементов определенного типа, для которых выделяется
оперативная память компьютера до начала выполнения программы обработки массива
на этапе компиляции. Такие массивы называются статическими.
В рассмотренном выше примере программного приложения размеры массивов А, В,
С неизменны и их объявление выполнено явно с использование константы, задающей
верхнюю и нижнюю границу диапазона, определяющего максимально допустимую
размерность массивов А, В, С. При компиляции программы под элементы массивов А, В
и С будет выделено по 100 полей памяти, в которые будет вводиться значение элементов
указанных массивов. Если конкретное количество элементов массивов меньше
максимального размера памяти, отведенного для их размещения, то часть
зарезервированной памяти остается неиспользованной, т.е. основной ресурс компьютера
— оперативная память — используется неэффективно.
13
В Delphi для устранения ситуации неэффективного использования памяти
компьютера при размещении в ней элементов массива определены динамические
массивы. Для объявления динамических массивов указывать диапазоны их измерения
не нужно. Например:
{описание одномерного динамического массива с элементами целого типа}
A: array of Integer;
{описание двумерного динамического массива с элементами символьного типа}
B: array of array of Char;
Распределение памяти и указание границ индексов по каждому измерению
динамических массивов осуществляется в ходе выполнения программы путем
инициации массива с помощью функции SetLength. В ходе выполнения оператора
SetLength(A, 3); одномерный динамический массив А будет инициирован, т.е получит
память, достаточную для размещения трех целочисленных значений. Нижняя граница
индексов по любому измерению динамического массива всегда равна 0, поэтому верхней
границей индексов для А станет 2. Фактически идентификатор динамического массива
ссылается на указатель, содержащий адрес первого байта памяти, выделенной для
размещения массива. Поэтому для освобождения этой памяти достаточно присвоить
идентификатору массива значение NIL, другим способом освобождения памяти является
использование процедуры Finalize.
На пример:
var
A, В: array of Integer; // А и В динамические массивы
begin
// Распределяем память:
SetLength (A, 10);
SetLength (В,20);
// Используем массивы:
<Строки кода программы обработки массива А и В>
// Освобождаем память:
A :=NIL.;
Finalize (В);
end.
После освобождения динамической памяти, она может быть использована для ввода
в нее других данных.
Рассмотрим пример описания динамических массивов и распределение памяти для их
размещения в процессе выполнения программного приложения для рассмотренного
выше примера, где массивы A, В и С были объявлены как статические. Стартовая форма
не изменится (см рис. 3), обработчики событий по формированию элементов массива A и
В в компонентах ListBoxl и LislBox2 не изменяются. Текст программы формирования
программы элементов массива С. и вывод их в компонент ListBox3 и пользовательская
процедура поиска максимального элемента в одномерном массиве также остается
14
неизменными.
Изменения для этого варианта программного приложения связанны, во-первых, с
объявлением массивов A, В и С как динамических в разделе Var в части Interface
модуля Unit1:
Var
// описание динамических массивов
A, В, С: array of integer;
Во-вторых, в обработчике событий формирования массива С использована функция
Setlength для выделения оперативной памяти компьютера мод конкретное количество
элементов массивов А, В и С, введенных в компоненты ListBox в процессе выполнения
программного приложения, а именно:
procedure TForm1.Button3Click(Sender: TObject);
begin
…………
m:=listboxl.Items.count;// количество элементов массива A
n:=listbox2.Items.count; // количество элементов массива В
// выделение динамической памяти
setlength( A, m); // выделение памяти массиву А
sellenglh(B, n); // выделение памяти массиву В
setlength(C, length(A)); // выделение памяти массиву С
…………
end;
Таким образом, в случае использования динамических массивов выделяется
столько памяти, сколько необходимо для обработки эле ментов массива.
Список учебной литературы
1. Литвина Е.М., Шаталова Л.М., Зиновьева Е.А. Разработка программных
приложений Delphi. Учебное пособие для лабораторных работ, под редакцией
Дегтярева А.В., М.: Издательство МАИ, 2006.
2. Афанасьева О.А., Дегтярев А.В., Зиновьева Е.А. , Литвина Е.М., Шаталова
Л.М. Информатика. Учебное пособие для студентов высших учебных заведений.
М.: Издательство «Доброе слово», 2010.
3. Фаронов В.В. DELPHI. Программирование на языке высокого уровня.
Учебник для ВУЗов. С-П, 2010.
15
Download