Опубликован: 10.04.2015 | Уровень: для всех | Доступ: свободно | ВУЗ: Компания ALT Linux
Лекция 5:

Использование языка Free Pascal для обработки массивов

< Лекция 4 || Лекция 5: 123456 || Лекция 6 >

5.8 Удаление элемента из массива

Знакомство с алгоритмом удаления элемента из массива начнем со следующей простой задачи. Необходимо удалить третий элемент из массива X, состоящего из 6 элементов. Алгоритм удаления третьего элемента заключается в том, что на место третьего элемента следует записать четвёртый, на место четвёртого — пятый, а на место пятого — шестой.

X[ 3 ] : =X [ 4 ];

X[ 4 ] : =X [ 5 ];

X[ 5 ] : =X [ 6 ];

Таким образом, все элементы с третьего по пятый надо переместить влево на один — на место i-го элемента нужно записать (i+1)-й. Блок-схема алгоритма представлена на рис. 5.25.

Алгоритм удаления 3-го элемента из массива

Рис. 5.25. Алгоритм удаления 3-го элемента из массива
Процесс удаления элемента из массива

Рис. 5.26. Процесс удаления элемента из массива
Алгоритм удаления m-го элемента из массива из n элементов

Рис. 5.27. Алгоритм удаления m-го элемента из массива из n элементов

Теперь рассмотрим более общую задачу: необходимо удалить m-й элемент из массива X, состоящего из n элементов. Для этого достаточно записать элемент (m+1)-й на место элемента c номером m, (m+2)-й элемент — на место (m+1)-го и т. д., n-й элемент — на место (n–1)-го. Процесс удаления элемента из массива представлен на рис. 5.26.

Алгоритм удаления из массива Х размерностью n элемента с номером m приведён на рис. 5.27.

После удаления элемента4А фактически сдвига части массива на один элемент влево из массива изменится количество элементов в массиве (уменьшится на один), и у части элементов изменится индекс. Если элемент удалён, то на место него приходит следующий, передвигаться к которому (путём увеличения индекса на один) нет необходимости. Следующий элемент сам сдвинулся влево после удаления.

Если обрабатывается массив, в котором часть элементов удаляется, то после удаления элемента не надо переходить к следующему (при этом уменьшается количество элементов). В качестве примера рассмотрим следующую задачу.

ЗАДАЧА 5.1. Удалить из массива X(n) отрицательные элементы.

Алгоритм решения задачи довольно прост: перебираем все элементы массива, если элемент отрицателен, то удаляем его путём сдвига всех последующих на один влево. Единственное, о чём стоить помнить, — что после удаления элемента не надо переходить к следующему для последующей обработки, он сам сдвигается на место текущего. Блок-схема решения задачи 5.1 представлена на рис. 5.28.

Ниже представлен текст программы с комментариями.

program upor_massiv;
var i, n, j : byte; X: array [ 1.. 100 ] of real;
	begin
	writeln ( ’введите размер массива  ’ ); readln ( n );
{Ввод массива.}
for i :=1 to n do
begin
write ( ’X[ ’, i, ’ ]= ’ );
readln (X[ i ] );
end;
writeln ( ’массив X  ’ );
for i :=1 to n do write ( x [ i ] : 5 : 2, ’   ’ );
writeln;
i : = 1;
while ( i<=n ) do
{Если очередной элемент массива X[i] отрицателен, то}
	if x [ i ]<0 then
	begin
{удаляем элемент массива с номером i.}
		for j := i to n_1 do
		x [ j ] : = x [ j + 1 ]; {Уменьшаем размер массива.}
{Не надо переходить к следующему элементу массива.}
		n:=n -1;
	end
else
{Если элемент не удалялся, то переходим к следующему элементу массива.}
i := i +1;
writeln ( ’Изменённый массив ’ );
for i :=1 to n do {Вывод преобразованного массива.}
write (X[ i ] : 5 : 2, ’   ’ ); writeln; end.
Блок-схема решения задачи 5.1

Рис. 5.28. Блок-схема решения задачи 5.1

Результаты работы программы представлены на рис. 5.29.

Результаты работы программы решения задачи 5.1

Рис. 5.29. Результаты работы программы решения задачи 5.1

5.9 Вставка элемента в массив

Рассмотрим несложную задачу: вставить число b в массив X(10), между третьим и четвёртым элементами.

Для решения этой задачи необходимо все элементы массива, начиная со четвёртого, сдвинуть вправо на один элемент. Затем в четвёртый элемент массива нужно будет записать b (X[4]:=b;). Но чтобы не потерять соседнее значение, сдвигать на один вправо нужно сначала десятый элемент, затем девятый, восьмой и т. д. до четвёртого. Блок-схема алгоритма вставки приведена на рис. 5.30.

Вставка числа b между третьим и четвёртым элементов массива X

Рис. 5.30. Вставка числа b между третьим и четвёртым элементов массива X

В общем случае блок-схема вставки числа b в массив X(N), между элементами c номерами m и m+1 представлена на рис. 5.31.

Вставка числа b в массив X

Рис. 5.31. Вставка числа b в массив X

Ниже представлен фрагмент программы, реализующий этот алгоритм5При описании массива X необходимо предусмотреть достаточный размер для вставки одного элемента..

	
var i, n,m: byte;
	X: array [ 1.. 100 ] of real;
b : real;
begin
	writeln ( ’N= ’ );
	readln ( n );
for i :=1 to n do
begin
write ( ’X[ ’, i, ’ ]= ’ );
	readln (X[ i ] );
end;
writeln ( ’Массив X ’ );
for i :=1 to n do write ( x [ i ] : 5 : 2, ’   ’ );
writeln;
writeln ( ’m= ’ );
readln (m);
writeln ( ’ b= ’ );
readln ( b );
for i :=n downto m+1 do
	x [ i +1]:=x [ i ];
x [m+1]:=b;
n:=n+1;
writeln ( ’Изменённый массив ’ );
for i :=1 to n do
	write (X[ i ] : 5 : 2, ’   ’ );
writeln;
end.

5.10 Использование подпрограмм для работы с массивами

Рассмотрим, как можно передавать массивы в подпрограмму. Как известно (см. главу 4), чтобы объявить переменные в списке формальных параметров подпрограммы, необходимо указать их имена и типы. Однако типом любого параметра в списке может быть только стандартный или ранее объявленный тип. Поэтому для того, чтобы передать в подпрограмму массив, необходимо вначале описать его тип6Тип данных массива, объявление массива см. в п. 2.4.9. Подробно работа с массивами описана в данной главе., а затем объявлять процедуру:

type

тип_массива = array [ список_индексов ] of тип;

procedure

имя_процедуры(имя_массива : тип_массива );

...

Например:

type
vector=array [ 1.. 10 ] of byte;
matrica=array [ 1.. 3, 1.. 3 ] of real;
procedure proc (A: matrica; b : vector; var x : vector );

Понятно, что передача в подпрограмму строки вида

имя_переменной : string [ длина_строки ];

которая фактически является массивом7Тип данных "строка", объявление строки см. в п. 2.4.9, должна осуществляться аналогично:

type

тип_строки = string [ длина_строки ];

procedure

имя_процедуры(имя_строки : тип_ строки );

...

Например:

type
stroka_5=string [ 5 ];
stroka_10=string [ 1 0 ];
function fun ( S t r : stroka_5 ) : stroka_10;

Массивы в подпрограмму можно передавать, используя понятие открытого массива. Открытый массив — это массив8Тип данных "массив", объявление массива, обращение к массиву см. в п. 2.4.9., при описании которого указывается тип элементов, из которых он состоит, но не определяются границы изменения индексов:

имя_открытого_массива : array of array of... тип;

Например:

var
massiv_1 : array of real;
massiv_2 : array of array of char;
massiv_3 : array of array of array of byte;

Распределение памяти и указание границ индексов по каждому измерению открытых массивов осуществляется в ходе выполнения программы с помощью функции SetLength:

SetLength (имя_открытого_массива, список_границ_индексов );

Для освобождения выделенной памяти нужно выполнить оператор:

имя_открытого_массива:=NIL;

Нижняя граница открытого массива (минимальное значение номера элемента) всегда равна нулю. Верхняя граница (максимальное значение номера элемента) возвращается стандартной функцией:

high (имя_открытого_массива)

Открытые массивы можно использовать при обычной обработке массивов в языке Free Pascal. Рассмотрим использование открытого массива на примере простейшей задачи нахождения суммы элементов массива.

var x : array of real; //Описание открытого массива.
	s : real;
	i, n : integer;
begin
write ( ’ n= ’ );
readln ( n );
//Выделяется память для размещения n вещественных значений:
SetLength ( x, n );
for i :=0 to high ( x ) do
read ( x [ i ] );
s : = 0;
for i :=0 to high ( x ) do
s := s+x [ i ];
writeln ( ’сумма= ’, s : 7 : 3 );
x:=NIL; //Освобождение памяти.
end.

Открытый массив может быть формальным параметром подпрограммы:

procedure имя_поцедуры(имя_открытого_массива : array of тип; );

Применение открытого массива в подпрограмме позволяет обрабатывать одномерные массивы произвольной длины:

//Процедура предназначена для вывода на экран
//сообщений о значениях элементов одномерного массива.
//Параметром подпрограммы является открытый массив целых
//чисел.
procedure outputArray (X: array of integer );
var i : byte;
begin
	//Элементы в открытом массиве пронумерованы от 0 до high(X).
	for i :=0 to high (X) do
	//Вывод сообщения: X[номер_элемента]=значение_элемента.
writeln ( ’X[ ’, i, ’ ]= ’,X[ i ] );
end;
var
	A: array [ 1.. 10 ] of integer;
	C: array of integer;
	i : byte;
begin
	//Формирование одномерного массива А из 10 элементов.
	for i :=1 to 10 do A[ i ] : = 2*i +1;
	//Выделяется память для размещения 3 целочисленных значений:
	SetLengTh (C, 3 );
	//Формирование одномерного массива С из 3 элементов.
	for i :=0 to 2 do C[ i ] : = 1-2*i;
	//Обращение к подпрограмме.
	outputArray (A);
	outputArray (C );
end.

Без использования открытых массивов процедуруoutputArray пришлось бы записать:

//Описание типа: массив целых чисел,
//пронумерованных от 0 до 10.
type massiv=array [ 0.. 10 ] of integer;
//Процедура предназначена для вывода на экран
//сообщений о значениях элементов одномерного массива.
procedure outputArray (X: massiv; nN, nK : byte );
//Параметры подпрограммы:
//1. Массив целых чисел X.
//2. Нижняя граница индекса nN.
//3. Верхняя граница индекса nK.
var i : byte;
begin
	//Элементы массива нумеруются от nN до nK.
	for i :=nN to nK do
writeln ( ’X[ ’, i, ’ ]= ’,X[ i ] );
end;
< Лекция 4 || Лекция 5: 123456 || Лекция 6 >
Юрий Шутиков
Юрий Шутиков

По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. 
 

Евгений Силуков
Евгений Силуков

Еще в декабре выполнил тест №1, а его все так и не проверили.

Юрий Макушин
Юрий Макушин
Россия, Москва, РЭА им. Плеханова, 2004