Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ситкин. Информатика. Программирование в DELPHI

.pdf
Скачиваний:
142
Добавлен:
18.07.2019
Размер:
1.49 Mб
Скачать

Procedure TForm1.Button1Click(Sender: TObject); var Cod:integer;

Begin

Val(Edit1.Text, n, Cod); //проверка синт-са и ввод n if (Cod < > 0) or (n<2) then //если ошибка, - то begin

Button2.Enabled:=False; //блокировка кнопки 2

ShowMessage('ошибка размера матрицы');

Exit; //досрочное завершение процедуры

end;

with StringGrid1 do //оператор присоединения -

begin //вып-е неск. действий с одним компонентом

 

RowCount:=n;

//установление числа строк

Рис. 9.6

ColCount:=n;

//установление числа столбцов

 

Visible:=True;

//сделать StringGrid1 видимым

 

end; //конец действий, выполняемых с компонентом

Button2.Enabled:=True; //активация кнопки 2

End; //конец первой процедуры

Procedure TForm1.Button2Click(Sender: TObject); var x:array of array of real; i, j:byte; Cod:integer;

Begin

Label2.Caption:=''; //очистка поля вывода при повт. щелчке SetLength(x, n, n); //выделение памяти под матрицу

for i:=0 to n 1 do //внешний цикл (перебор строк) begin //начало тела внешнего цикла

for j:=0 to n 1 do //вложенный цикл (перебор столбцов) begin //начало тела вложенного цикла

Val(StringGrid1.Cells[i, j], x[i, j], Cod); //ввод xij

if Cod <>0 then begin //если ошибка синтаксиса, то Рис. 9.7

Label2.Caption:=''; //очистка поля вывода

ShowMessage('ошибка синтаксиса в матрице'); SetLength(x, 0, 0); Exit; //высвоб. памяти и выход

end; //конец действий для случая синтакс. ошибки

if i=j then x[i,j]:=2*x[i, j]; //удв-е элемента, если он на главной диагон.

Label2.Caption:=Label2.Caption+#9+FloatToStr(x[i, j]); //вывод xij

end; //конец тела вложенного цикла

Label2.Caption:=Label2.Caption+#13; //перевод строки вывода

end; //конец тела внешнего цикла

SetLength(x, 0, 0); //высвобождение памяти хранения элементов матрицы End; END. //конец второй процедуры и конец модуля проекта

111

Сортировка массивов

Сортировка массива процесс упорядочивания набора одно-

типных данных по возрастанию или убыванию значения какого-либо признака. При сортировке числового массива его элементы меняются местами таким образом, что их значения оказываются упорядочен-

ными по возрастанию или убыванию. Сортировка является важным действием над массивами в системах поиска данных, т.к. в отсорти-

рованных массивах процесс поиска значительно ускоряется.

Существует много алгоритмов сортировки, которые отличают-

ся друг от друга по скорости работы, что заметно на больших масси-

вах, для небольших массивов можно использовать простые из них.

Сортировка методом обмена (метод «пузырька»)

Суть данного метода сортировки по возрастанию состоит в сле-

дующем. Каждый элемент массива, начиная с первого и заканчивая предпоследним, сравнивается со следующим элементом. Если теку-

щий элемент больше следующего, то элементы меняются местами.

Циклический процесс просмотра всех элементов массива повторяется столько раз, сколько элементов в массиве минус единица. Таким об-

разом более «лёгкие» элементы массива постепенно продвигаются к началу («всплывают»), а более «тяжёлые» к концу («тонут»). Этот алгоритм простой, но очень медленный. Его можно несколько уско-

рить, если массив изначально частично отсортирован. Для этого вво-

дится переменная-признак, контролирующая процесс обмена. Если при очередном просмотре массива не было ни одной перестановки, то это значит, что массив отсортирован и, в соответствии со значением переменной-признаком, процесс завершается.

112

На рис. 9.8 представлена блок-схема описанного алгоритма сор-

тировки. Чтобы не отвлекаться на второстепенные действия ввода и вывода массива, процесс сортировки представлен в виде пользова-

тельской процедуры, причём с формальным открытым параметром-

массивом, что позволит сортировать передаваемые в процедуру фак-

тические массивы произвольной длины. Напомним, что нумерация элементов у такого массива начинается с нуля. Для возможности воз-

врата в вызывающий блок, массив сделан параметром-переменной.

procedure Sort_obmen(var t:array of real);

начало

var buf:real; //для временного хранения элемента

f = false

k:byte;

k = 0

f:boolean; //переменная-признак

k число нет

э-ов 2

да

tk tk+1 нет

да

buf = tk

tk = tk+1 tk = buf

f = true

/обмен был/

k = k + 1

нет

f true

 

да

конец

Рис. 9.8

begin

repeat //внешний цикл контроля обменов f:=false; //пусть обменов не было

for k:=0 to high(t)-1 do //от начального до

//предпоследнего элемента массива (напомним,

//ф-я high сама отнимает единицу от числа эл-ов) if t[k]>t[k+1] then //если текущий элемент begin //больше следующего, то поменять их

buf:=t[k]; //местами с использованием t[k]:=t[k+1]; //буферной переменной

t[k+1]:=buf;

f:=true; //обмен состоялся

end;

until not f; //до тех пор, пока обмен не состоялся

end;

113

Сортировка методом выбора Суть данного метода сортировки по возрастанию состоит в сле-

дующем. Начиная с первого элемента, просматривается массив, нахо-

дится минимальный элемент, который ставится на место первого, а

 

начало

 

 

первый занимает место минимального. Затем,

 

 

 

 

 

 

 

 

начиная со второго элемента, просматривается

 

m = 0

 

 

 

 

 

оставшаяся часть массива, находится мини-

 

 

 

 

 

 

 

 

мальный элемент, который меняется местами

 

 

 

 

 

m число

нет

 

 

э-ов 2

 

 

со вторым, и т.д. до предпоследнего элемента.

 

да

 

 

Блок-схема описанного алгоритма представ-

 

 

 

 

 

min = m

 

 

 

 

 

лена на рис. 9.9. Как и в предыдущем методе,

 

 

 

 

 

n = m + 1

 

 

процесс сортировки оформим в виде пользо-

 

 

 

 

 

n число

нет

 

вательской процедуры с открытым массивом.

 

э-ов 1

 

 

 

 

да

 

 

procedure Sort_vubor(var t:array of real);

 

tn < tmin

нет

var buf:real;

 

 

 

 

 

да

 

 

min, m, n:byte;

min = n

n = n + 1

buf = tm

tm = tmin

tmin = buf

m = m + 1

конец

Рис. 9.9

begin

for m:=0 to high(t)-1 do //от начального до

begin //предпоследнего элемента массива min:=m; //пусть номер миним. эл-та равен m

for n:=m+1 to high(t) do //цикл поиска миним. if t[n]<t[min] then min:=n; //элемента

buf:=t[m]; //перестановка первого элемента t[m]:=t[min]; //в оставшейся последовательности t[min]:=buf; //с минимальным через буф. пер-ную

end;

end;

114

Пример 9.3

 

 

 

 

 

 

 

 

 

 

 

 

Разработаем проект для построчной сортировки по возрастанию

начало

 

 

элементов двумерного массива пе-

 

 

 

 

 

 

 

 

 

 

 

 

 

m = число

 

 

ременной длины строк.

 

 

 

 

 

 

Разделим задачу на две части.

строк

 

 

 

выделить па-

 

 

В первой части щелчком по кнопке

 

 

 

 

 

 

 

 

 

 

 

 

 

мять под m

 

 

Button1 сформируем таблицу String-

элементов

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Grid для ввода элементов, которую

номер строки

 

 

 

 

 

 

 

 

 

 

 

 

 

i = 0

 

 

изначально

сделаем

невидимой.

 

 

 

Для

задания

пользователем

числа

i m 1

нет

число столб.=m

элементов

каждой

строки

разме-

число стр.=max

 

 

таблица видна

стим на форме

компонент

Memo,

да

 

 

ввод yi эл-та

 

кнопка сорти-

тем

самым

будет

определено

и

c проверкой

 

ровки строк

 

 

 

 

 

 

 

 

 

 

 

 

синтаксиса

 

доступна

число

строк

двумерного

массива

 

 

 

 

1

(таблицы). На рис. 9.10 изображена

ошибка

 

 

да

 

 

 

 

 

 

 

 

 

 

 

 

или yi 2

 

 

блок-схема алгоритма первой части

нет

 

 

(обработка

события

Button1Click).

 

 

кнопка сорти-

 

нет

 

 

 

 

 

 

 

 

 

 

 

i = 0

ровки строк

По

числу

заполненных

строк

в

 

 

 

недоступна

 

 

 

 

 

 

 

 

 

 

 

да

 

 

Memo выделяется память под мас-

max = y0

 

ошибка

 

 

 

 

 

 

 

 

 

 

 

 

длины

сив хранения длин строк таблицы.

 

 

строки

 

 

 

 

 

 

 

 

 

 

 

 

 

 

В теле цикла, контролируя синтак-

 

нет

высвободить

сис

и

длину,

вводятся

размеры

yi > max

память из-под

 

 

m элементов

строк

в

массив,

и

параллельно

да

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

определяется максимальное значе-

max = yi

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

конец

ние массива. Вне тела формируется

 

 

 

i = i + 1

 

 

размер таблицы по числу строк в

 

 

Memo и максимальному числу эле-

 

 

 

 

 

Рис. 9.10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

115

 

 

 

 

 

 

 

 

 

 

 

 

начало

 

 

 

 

 

 

 

 

номер строки

 

 

 

i = 0

 

 

 

 

 

 

 

 

 

i m 1

нет 1

 

 

да

 

 

 

 

выделить па-

 

 

 

мять под i-ую

 

 

 

строку

 

 

 

 

 

 

 

 

 

 

 

 

номер элемента

 

 

 

в i-ой строке

 

 

 

 

j = 0

 

 

 

 

 

 

 

 

 

j yi 1

нет

 

 

 

 

 

 

да

 

 

 

 

ввод zj эл-та

 

 

j = j + 1

 

c проверкой

 

 

 

 

синтаксиса

 

 

нет ошибка

синтакси-

ошибка да са

синтаксиса в таблице

1

 

сортировка

 

 

 

 

 

 

 

 

i-ой строки

 

 

высвободить

 

 

 

 

 

 

 

 

память из-под

 

 

 

 

 

номер элемента

 

i-ой строки

 

 

 

в i-ой строке

 

 

 

 

 

 

 

 

 

конец

 

j = 0

 

 

 

 

 

 

 

j yi 1

нет

 

 

 

 

 

 

 

 

да

 

 

j = j + 1

 

вывод zj

 

 

 

 

 

 

 

i = i + 1

перевод

 

строки

 

 

вывода

Рис.9.11

 

 

ментов одной из строк. Сама таблица становится видимой, а кнопка сортировки строк Button2

(изначально недоступная) до-

ступной. Нарушение допусти-

мости размера любой из строк приводит к выводу сообщения об ошибке, высвобождению па-

мяти из-под массива хранения длин строк и недоступности кнопки Button2.

Во второй части задачи (обработка события Button2Click),

рис. 9.11, во внешнем цикле вы-

деляется память под элементы текущей строки таблицы. Затем в первом вложенном цикле они записываются в одномерный массив (если нет ошибок), вне тела этого цикла сортируются процедурой Sort_obmen (с от-

крытым массивом, т.к. строк не-

сколько и они разных длин) и во втором вложенном цикле выво-

дятся в компонент Label. Затем всё повторяется для следующей строки и т.д.

116

IMPLEMENTATION

{$R *.dfm}

var m:byte; //глобальная переменная, т.к. используется в двух процедурах y:array of byte; //глобальный динамический массив длин строк

Procedure Sort_obmen(var t:array of real); //пользовательская процедура

var buf:real; k:byte; f:boolean;

Begin repeat

f:=false;

for k:=0 to high(t)-1 do if t[k]>t[k+1] then begin

buf:=t[k]; t[k]:=t[k+1]; t[k+1]:=buf; f:=true;

end;

until not f;

End; //конец пользовательской процедуры сортировки одномерного массива

Procedure TForm1.Button1Click(Sender: TObject); var i, max:byte; Cod:integer;

Begin

m:=Memo1.Lines.Count; //определение числа строк в Memo

SetLength(y, m); //выделение памяти под массив хранения длин строк for i:=0 to m-1 do //цикл перебора строк в Memo

begin //начало тела цикла

Val(Memo1.Lines[i], y[i], Cod); //ввод в массив длины i-ой строки

if (Cod<>0) or (y[i]<2) then //если синт. ошибка или недопуст. длина

begin //то

Button2.Enabled:=False; //кнопка сортировки строк недоступна

ShowMessage('ошибка длины строки'); //вывод сообщения

SetLength(y,0); Exit; //высвободить память и досрочный выход end; //конец действий для случая ошибки

if i=0 then max:=y[0]; //пусть нулевая строка максимальной длины if y[i]>max then max:=y[i]; //поиск самой длинной строки

end; //конец тела цикла

with StringGrid1 do begin //формирование таблицы для ввода значений

RowCount:=m;

ColCount:=max;

Visible:=True;

end;

Button2.Enabled:=True; //кнопка сортировки строк доступна End; //конец процедуры формирования таблицы

117

Procedure TForm1.Button2Click(Sender: TObject); var i, j:byte; Cod:integer; z:array of real;

Begin

Label2.Caption:=''; //очистка поля вывода при повторном щелчке for i:=0 to m-1 do //внешний цикл – перебор строк таблицы begin //начало тела внешнего цикла

SetLength(z, y[i]); //выделение памяти под i-ую строку

for j:=0 to y[i]-1 do //первый вложенный цикл – ввод i-ой строки таблицы begin //начало тела первого вложенного цикла

Val(StringGrid1.Cells[j, i],z[j], Cod); //ввод j-го элемента i-ой строки

if Cod<>0 then begin //если синтаксическая ошибка

Label2.Caption:=''; //очистка поля вывода

ShowMessage('ошибка синтаксиса в таблице'); SetLength(z, 0); Exit; //высвоб. память и доср. выход

end; //конец действий для случая синтаксич. ошибки end; //конец тела первого вложенного цикла

Sort_obmen(z); //сортировка элементов i-ой строки таблицы

for j:=0 to y[i]-1 do //второй влож. цикл – вывод отсортиров-ой строки

Label2.Caption:= Label2.Caption+#9+FloatToStr(z[j]); Label2.Caption:= Label2.Caption+#13; //перевод строки вывода

end; //конец тела внешнего цикла

SetLength(z, 0); //высвобождение памяти из-под массива значений таблицы end; END. //конец процедуры построчной сортировки и конец модуля

Память из-под массива y длин строк не высвобождалась, т.к. она выделяется во второй процедуре, а массив используется и в третьей,

кроме того, возможен повторный щелчок пользователем по кнопке Button2 без щелчка по Button1, поэтому и в третьей процедуре освобо-

дить память нельзя. В данном примере представляет интерес вопрос выделения памяти, по-

этому он отражён в блок-

схемах, что необычно. На рис. 9.12 представлен пример рабо-

ты приложения.

Рис. 9.12

118

Задание

Разработать проект для ввода с формы элементов прямоуголь-

ной матрицы задаваемого пользователем размера и

1.Умножить элементы 1-ой строки и 1-го столбца на коэффициент.

2.Найти суммы элементов каждой строки и всех элементов.

3.Найти суммы элементов каждого столбца и всех элементов.

4.Найти столбец с наименьшей суммой элементов.

5.Найти строку с наибольшей суммой элементов.

6.Определить есть ли заданный элемент, указать его положения.

7.Определить число положительных элементов в каждой строке.

8.Определить число нечётных элементов в каждом столбце.

9.Найти наибольший элемент, указать его положение.

Содержание отчёта

цель работы и задание;

блок-схемы алгоритмов формирования и обработки матрицы;

текст модуля проекта;

пример работы приложения с указанием компонентов формы;

выводы по работе.

Контрольные вопросы

 

1. Приведите примеры описаний

3. Какое значение получит k?

двумерных массивов, почему для

var i, j, k: byte;

их обработки требуются кон-

i:=1; k:=0;

струкции с вложенными циклами?

while i<3 do begin

2. Как выделить память под не-

inc(i);

прямоугольный двумерный дина-

for j:=1 to i do inc(k);

мический массив?

end;

119

Лабораторная работа № 10

ВНЕШНИЕ ФАЙЛЫ

Цель работы приобретение умений организации обмена данными между приложением и внешними файлами.

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

Физические и логические файлы

Файл именованный набор данных одного типа практически произвольной длины, хранящихся на внешнем носителе данных в областях памяти, разделённых на кластеры. Размер файла ограничивается только ёмкостью носителя данных. Организация хранения зависит от конкретного носителя. Файл в таком понимании называют физическим файлом. Для организации работы с физическими файлами в языках программирования предусмотрены специальные структуры данных тип данных файл. Файл в таком понимании называют логическим файлом (файловой переменной), так как в этом случае он представляет собой лишь логическую модель хранения данных, не зависящую от организации конкретного физического файла.

120