Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
osnovy_programmirovanija_v_srede_lazarus.pdf
Скачиваний:
182
Добавлен:
18.03.2015
Размер:
6.53 Mб
Скачать

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

Процедура находится в модуле OutScr}

output_to_screen(name_file);

if n= -1 then

writeln(UTF8ToConsole('Такого менеджера нет'))

else

writeln(UTF8ToConsole('Менеджер найден, его номер '),

n+1);

write(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

4.2.2 Вставка и удаление элементов в упорядоченном массиве

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

ство данных. "Приличная" система должна давать пользователям возможность корректирования введенных данных, т.е. вставки новых данных, изменения уже введенных данных и удаления данных. Задача эта не столь тривиальна, как мо-

жет показаться на первый взгляд. Пусть необходимо вставить новый элемент x

в упорядоченный по возрастанию массив a[1..n] в место с номером k, где k<n.

Если просто присвоить a[k]:= x;

то элемент с индексом k, который находился там ранее, будет потерян.

Следовательно, предварительно необходимо сдвинуть все элементы a[k], a[k+1], …, a[n] на одну позицию вправо. Это можно сделать с помощью цикла:

for i:= n downto k do

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

323

4.2 Алгоритмы поиска

____________________________________________________________________

inc(n);

То же самое при удалении элемента из массива. Если удаляется элемент a[k], то все оставшиеся элементы a[k+1], …, a[n] надо сдвинуть на одну пози-

цию влево, чтобы закрыть возникшую "дыру" в k-й позиции массива.

Код для сдвига элементов массива при удалении элемента a[k] будет та-

ким:

for i:= k + 1 to n do

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

dec(n);

Напишем программу вставки нового элемента в массив. Предположим, что массив состоит из целых чисел 1, 2, 3, 4. Моделируем ситуацию, когда пользо-

ватель при вводе массива допустил ошибку, пропустил число 3. Поскольку оператор readln "не реагирует" на ввод пустой строки, была введена следую-

щая последовательность чисел: 1, 2, 4, 5. Необходимо дать пользователю воз-

можность откорректировать данные, введенные им в массив.

program project1; uses

CRT, FileUtil; var

i, n: integer;

a: array of integer; NewElement: integer; IndexOfNewElement: integer; SizeOfArray: integer; answ: char;

324

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

begin

writeln(UTF8ToConsole('Введите размер массива')); readln(SizeOfArray);

SetLength(a, SizeOfArray); writeln(UTF8ToConsole('Введите элементы массива')); for i:= 0 to SizeOfArray - 1 do

read(a[i]); writeln(UTF8ToConsole('Введен массив:')); for i:= 0 to SizeOfArray - 1 do write(a[i], ' '); writeln;

writeln(UTF8ToConsole('Откорректируйте данные')); writeln(UTF8ToConsole('Если все правильно, нажмите Enter,')); writeln(UTF8ToConsole('иначе - любую клавишу'));

answ:= readkey;

if answ = #13 then exit; writeln(UTF8ToConsole('Введите новый элемент')); readln(NewElement); writeln(UTF8ToConsole('Введите индекс в массиве,'));

writeln(UTF8ToConsole('куда нужно вставить новый элемент')); readln(IndexOfNewElement);

for i:= SizeOfArray - 1 downto IndexOfNewElement do a[i+1]:= a[i];

a[IndexOfNewElement]:= NewElement;

if IndexOfNewElement= SizeOfArray then inc(SizeOfArray);

writeln(UTF8ToConsole('Массив после вставки нового элемента'));

for i:= 0 to SizeOfArray - 1 do

write(a[i], ' '); writeln;

writeln(UTF8ToConsole('Нажмите любую клавишу'));

325

4.2 Алгоритмы поиска

____________________________________________________________________

readkey;

end.

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

грамме пользователь сам вводил индекс в массиве, куда нужно вставить новый элемент. Оказывается, алгоритм бинарного поиска позволяет автоматически вставлять новый элемент в нужное место. Каким образом? Рассмотрим на кон-

кретном примере. Пусть имеется массив из 5 элементов. Необходимо вставить число 3. Вспомним алгоритм бинарного поиска. Первоначальное расположение

указателей будет, так как показано на рисунке 4.12.

 

1

2

4

5

6

left

 

middle

 

right

 

Рис. 4.12. Начальное расположение указателей

При этом значения переменных будут равны:

key = 3, left = 0 (не забывайте, нумерация в динамических массивах с нуля!) right = 4, middle = (left+right) div 2 = (0 + 4) div 2 = 2

a[middle] = a[2] = 4

key = 3 < a[2] = 4, т.е. значение ключа меньше значения среднего элемента.

Согласно алгоритму, переменной right будет присвоено значение:

right = middle - 1 = 2 - 1 = 1

middle = (left+right) div 2 = (0 + 1) div 2 = 1

Новое расположение указателей показано на рисунке 4.13.

1 2 4 5 6

left middle right

Рис. 4.13. Новое расположение указателей

326

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

a[middle] = a[1] = 2

key = 3 > a[1] = 2, т.е. значение ключа больше значения среднего элемента,

следовательно, переменной left будет присвоено значение left = middle + 1 = 1 + 1 = 2

Значение left оказывается больше right: left = 2 > right = 1

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

Но, посмотрите чему равно значение left. Оно равно 2, т.е. как раз тому индексу

вмассиве, куда должен быть помещен новый элемент, т.е. key равный 3!

Валгоритме достаточно изменить один оператор, в том месте, где функция

BinarySearch возвращает -1 (элемент не найден!), т.е. вместо

BinarySearch:= -1;

необходимо записать

BinarySearch:= left;

Итак, улучшенная программа предыдущего примера. В этой программе вставка нового элемента оформлена в виде процедуры. Кроме того, введены проверки на правильность ввода размера массива

program modify_insert;

uses

CRT, FileUtil;

var

i: integer;

a: array of integer;

NewElement: integer;

327

4.2 Алгоритмы поиска

____________________________________________________________________

IndexOfNewElement: integer; SizeOfArray: integer; answ: char;

function BinarySearch(var a: array of integer; key: integer): integer;

var

left, right, middle: integer; begin

left:= Low(a); right:= High(a); repeat

middle:= (left + right) div 2; if key < a[middle] then

right:= middle - 1 else

if key > a[middle] then left:= middle + 1

else begin

BinarySearch:= middle; exit;

end;

until left > right; BinarySearch:= left;

end;

procedure insert_new_element(var a: array of integer;

var NewElement: integer; var IndexOfNewElement: integer); begin

for i:= SizeOfArray - 1 downto IndexOfNewElement do

328

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

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

a[IndexOfNewElement]:= NewElement;

if IndexOfNewElement= SizeOfArray then

inc(SizeOfArray);

end;

begin

writeln(UTF8ToConsole('Введите размер массива')); while true do

begin readln(SizeOfArray); if SizeOfArray = 0 then begin

writeln(UTF8ToConsole('Размер массива не может быть = 0')); writeln(UTF8ToConsole('Введите размер массива'));

end else

if SizeOfArray < 0 then begin

writeln(UTF8ToConsole('Размер массива не может быть < 0')); writeln(UTF8ToConsole('Введите размер массива'));

end

else break; end;

SetLength(a, SizeOfArray); writeln(UTF8ToConsole('Введите элементы массива')); for i:= 0 to SizeOfArray - 1 do

read(a[i]); writeln(UTF8ToConsole('Введен массив:')); for i:= 0 to SizeOfArray - 1 do

329

4.2 Алгоритмы поиска

____________________________________________________________________

write(a[i], ' '); writeln; writeln(UTF8ToConsole('Откорректируйте данные')); writeln(UTF8ToConsole('Если все правильно, нажмите Enter,')); writeln(UTF8ToConsole('иначе - любую клавишу'));

answ:= readkey;

if answ = #13 then exit; writeln(UTF8ToConsole('Введите новый элемент')); readln(NewElement);

IndexOfNewElement:= BinarySearch(a, NewElement); insert_new_element(a, NewElement, IndexOfNewElement);

writeln(UTF8ToConsole('Массив после вставки нового элемента'));

for i:= 0 to SizeOfArray - 1 do

write(a[i], ' '); writeln;

writeln(UTF8ToConsole('Нажмите любую клавишу'));

readkey;

end.

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

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

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

if IndexOfNewElement = SizeOfArray then inc(SizeOfArray);

на просто оператор инкремента

330

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]