Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции ИВАНОВ Книга Паскаль.doc
Скачиваний:
5
Добавлен:
18.11.2019
Размер:
1.93 Mб
Скачать

Глава 4

Массивы

М ассив - это упорядоченная последовательность величин, имеющих один и тот же тип и объединённых одним именем.

Число элементов массива задаётся при описании и в процессе выполнения программы не меняется. Имя массива образуется аналогично имени любой другой величины. Отдельные величины, составляющие массив, называются элементами массива. При обращении к элементу массива, необходимо указывать его имя, а в квадратных скобках его индексы.

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

Элементы массива могут быть использованы так же, как и простые переменные. Например, они могут находиться в выражениях в качестве операндов, использоваться в операторах for, while, repeat, входить в качестве параметров в операторы Read, Write, им можно присваивать любые значения, соответствующие их типу. Индексы массива должны быть целого типа, и индексы могут иметь как положительные, так и отрицательные значения, а также индексы могут быть нулями.

Если элемент массива имеет только один индекс, массив называется одномерным, если два индекса - двухмерным.

4.1 ОДНОМЕРНЫЕ МАССИВЫ

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

Формат:

<имя> : array[n .. m] of <тип>;

где имя – имя переменной-массива;

array – зарезервированное слово, обозначающее, что переменная является массивом;

n, m – нижний и верхний индексы, целые константы, определяющие диапазон изменения индексов элементов массива (т.е. размер массива);

тип – тип элементов массива.

Описание одномерных массивов можно произвести в следующих разделах:

  • В разделе объявления переменных

Var a: array[1..100] of integer; {100 элементов – целые числа}

b: array[1..50] of char; {51 элемент - символы}

c: array[-3..4] of boolean; {8 элементов – логические значения}

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

  • В разделе констант

Const i=14;

Var a: array[1..i] of real;

Употребление констант при описании массива предпочтительно, т.к. в случае изменения размеров массива не нужно будет вносить исправления по всему тексту программы, достаточно только один раз изменить значение именованной константы.

  • В разделе описания типов

Type d=array[1..23] of real;

Var a, b, c: d;

Приведем примеры неправильного описания массивов:

a: array [ ] of real; {не определены размерность и границы диапазонов}

b: array [10..1] of integer; {значение нижней границы массива превышает значение верхней}

c: array [1..a+b] of real; {границы массива необходимо задать константой, а не выражением}

d: array [1.0..100.0] of integer; {недопустимо использовать вещественные числа для границ индексов}

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

Например, дан массив B из 3 элементов (b1=3, b2= -14, b3=25), тогда, чтобы обратиться ко второму элементу, нужно записать: b[2].

Запись В(3) означает, что массив B состоит из трёх элементов. Часто вместо слова “массив”, используют понятие “последовательность чисел”. Например: дан массив S(4) и дана последовательность чисел S1, S2, S3, S4 - это означает одно и тоже, поэтому и описываются совершенно одинаково.

Необходимо четко различать индекс элемента массива и значение элемента. Например, в операторе a[3]:=1; число 3 – это индекс (номер) элемента массива, а 1 – значение, которое ему присваивается.

Примеры ошибочного обращения к элементам массивов:

var f: array [1..10] of real;

f [5.0]… {использование вещественного индекса запрещено}

f [1,4]… {несоответствие размерности – к вектору обращаются как к матрице}

Следует знать:

  • границы изменения индексов должны быть константами, причем очень удобно использовать именованные константы;

  • нижняя граница индекса чаще всего равна 1, т.е. обычно элементы массива нумеруются, начиная с единицы (иногда нумерация начинается с нуля);

например,

var x: array [0..50] of integer; {массив содержит 6 элементов, номера с нулевого по пятый}

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

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

4.2 ДВУМЕРНЫЕ МАССИВЫ

Массивы с двумя индексами называют в математике матрицами.

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

Формат:

<имя> : array[n1..n2, m1..m2] of <тип>;

Здесь величины n1 и n2 (индексы строки), m1 и m2 (индексы столбца) являются целочисленными константами.

Описание двумерных массивов производится аналогично описанию одномерных массивов:

  • в разделе описания типов

Type zatrat = array[1..5, 1..5] of real;

Var a : zatrat;

  • в разделе констант

Const i=5; j=7;

Var S: array[ 1..i, 1..j ] of integer;

  • в разделе объявления переменных

Var А: array[1..5, 1..6] of real;

Запись А(5,7) означает, что речь идёт о двумерном массиве, в котором 5 строк и 7 столбцов.

Запись А[5,7] означает, что речь идёт об элементе двумерного массива, который находится в пятой строке и в седьмом столбце массива А.

4.2.1 Квадратные матрицы

Квадратные матрицы (число строк равно числу столбцов) имеют главную и побочную диагонали.

а11 а12 а13

А = а21 а22 а23

а31 а32 а33

Если:

  • i = j - элементы расположены на главной диагонали (а11, а22, а33).

  • i < j - элементы расположены выше главной диагонали (а12, а13, а23).

  • i > j - элементы расположены ниже главной диагонали (а21, а31, а32).

  • i + j = n + 1 (n – размерность матрицы) — элементы расположены на побочной диагонали (а13, а22, а31).

  • i + j < n + 1— элементы расположены над побочной диагональю.

  • i + j > n + 1— элементы расположены под побочной диагональю.

4.3 ДЕЙСТВИЯ НАД МАССИВАМИ

Если указываются в квадратных скобках индексы, то такое обращение к массиву называется поэлементным. Но с массивом можно работать и как с единым объектом. При работе с массивом как с единым целым используется имя массива без указания индекса в квадратных скобках. При этом к массиву может применять только операции отношения “равно”, “не равно” и оператор присваивания. Массивы, участвующие в этих действиях, должны иметь одинаковые типы индексов и одинаковые типы компонент.

Например, если массивы А и В описаны как:

Var A: array[1..16,1..5] of real;

B: array[1..16,1..5] of real;

то применение к ним допустимых операций даст следующий результат:

  • А=В

Результатом данного сравнения будет истина, если значение каждого элемента массива А совпадает со значением соответствующего элемента массива В. В противном случае результат будет ложным.

  • А<>B

Результат данного сравнения будет истинным, если хотя бы одно значение элемента массива А не равно значению соответствующего элемента массива В. результат будет ложным, если все элементы массива А равны соответствующим элементам массива В.

  • A:=B

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

4.4 ДЕЙСТВИЯ НАД ЭЛЕМЕНТАМИ МАССИВА

Рассмотрим два массива, описанных в разделе констант:

Const k=4; n=12; m=23;

Var A: array[1..k] of real;

D: array[ 1..n,1..m] of real;

i, j: integer;

4.4.1 Ввод элементов массива

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

I способ – ввод элементов последовательно через клавиатуру:

для одномерного массива

for i:=1 to k do read(A[i]);

для двумерного массива

for i:=1 to n do

for j:=1 to m do read(D[i,j])

II способ – вычисление значений элементов массива по заданным формулам:

для одномерного массива

for i:=1 to k do A[i]:=f(x);

для двумерного массива

for i:=1 to n do

for j:=1 to m do D[i,j] :=f(x);

III способзадание массива с помощью функции-генератора случайных чисел:

для одномерного массива

randomize; {инициализация датчика случайных чисел}

for i:=1 to k do A[i]:=random;

для двумерного массива

randomize; {инициализация датчика случайных чисел}

for i:=1 to n do

for j:=1 to m do D[i,j] :=random;

4.4.2 Вывод элементов массива

Под выводом массива понимается вывод всех значений элементов массива с использованием операторов Write, Writeln.

Вывод элементов для одномерного массива (вектора):

  • в одну строку, через пробел-разделитель:

for i := 1 to k do Write(A[i], ‘ ‘);

  • в столбец:

for i := 1 to k do Writeln(A[i]);

  • с заданием формата, где под каждый элемент отводится 4 позиции:

for i := 1 to k do Write(A[i]:4);

Вывод элементов для двумерного массива (матрицы)

  • вывод элементов массива в одну строку

for i := 1 to n do

for i := 1 to m do Write(D[i,j]:4);

  • вывод элементов массива в один столбец

for i:=1 to n do

for j:=1 to m do Writeln(D[i,j]);

  • вывод элементов массива в стандартной форме записи – по строкам и столбцам - выполняется при помощи оператора Writeln (без параметра). Он используется после вывода текущей строки матрицы для перевода курсора в начало следующей строки экрана:

for i:=1 to n do

begin

for j:=1 to m do write(D[i,j]:4);

writeln {переход на новую строку}

end;

Задание формата вывода помогает расположить матрицу на экране ровными столбцами.

4.4.3 Обработка элементов одномерного массива

  • Вычисление суммы элементов

S:=0;

for i:=1 to k do S:=S+A[i]; {обычное накопление суммы в S}

  • Вычисление произведения элементов

S:=1;

for i:=1 to k do S:=S*A[i]; {накопление произведения в S}

  • Подсчет количества элементов, удовлетворяющих какому-либо условию

r:=0;

for i:=1 to k do

if A[i] mod 2 =0 then r:=r+1; {увеличиваем на 1 счетчик четных чисел}

  • Поиск максимального элемента и его номера

Переменные max – хранит значение максимума,

p – его номер в массиве.

max:=a[1]; {поиск начинаем с первого элемента}

p:=1;

for i:=2 to k do {перебираем элементы, начиная со второго}

if A[i] >max then

begin

max:=A[i]; p:=i; {запоминаем значение и номер элемента, который больше всех предыдущих}

end;

  • Перестановка элементов в массиве

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

buf:=A[1];

A[1]:=A[2];

A[2]:=buf;

4.4.4 Обработка элементов двумерного массива

  • Суммирование элементов каждой строки

for i:=1 to n do

begin

S:=0;

for j:=1 to m do S:=S+D[i,j];

end;

  • Суммирование элементов каждого столбца вычисляется аналогично. Для этого внешний цикл необходимо сделать по переменной j (номер столбца), а внутренний – по i (номер в строке).

for j:=1 to m do

begin

S:=0;

for i:=1 to n do S:=S+D[i,j];

end;

  • Поиск минимального элемента всей матрицы и его номера.

Переменные min – хранит значение минимального элемента,

p – номер строки, h - номер столбца, где он находится.

min:=D[1,1];

p:=1;

h:=1;

for i:=1 to n do

for j:=1 to m do

if D[i,j] <min then begin min:=D[i,j]; p:=i; h:=j end;

4.5 ПРИМЕРЫ ЗАДАЧ НА МАССИВЫ

Пример. Дан целочисленный массив С(15). Найти сумму элементов C1+C2+…+C15.

program Summa ;

Var C : array[1..15] of integer;

s, i : integer;

Begin

S:=0;

for i:=1 to 15 do

begin

read(C[i]); {ввод массива}

s:=s+C[i]; {суммирование элементов массива}

end;

Write(s)

end.

В программе организован цикл для ввода одномерного массива с клавиатуры, в нем же производится в переменной S накапливание суммы элементов массива. После окончания цикла выводится значение переменной S.

Пример. Заполнить массив, применив для его заполнения следующее значение: a[i]=(x*i2)/(i+x). Найти сумму элементов массива, имеющих нечетные номера.

program Sozd_massiv ;

Const n=10;

Var a : array[1..n] of real;

i : integer; x, S : real;

begin

Write(‘Введите значение х:‘);

Readln(x);

for i:=1 to n do

begin

a[i]:=x*sqr(i)/(i+x);{создание массива}

Write(a[i]:8:4)

end;

S:=0;

for i:=1 to n do

if i mod 2<>0 then S:=S+a[i];

Write(‘Сумма = ‘, S:4:2)

end.

Перед оператором ввода Readln(x) выполняется оператор вывода Write(‘Введите значение х:‘), который представляет собой подсказку для пользователя при вводе исходной информации.

В программе организованы два цикла, в первом из которых производится вычисление каждого элемента массива по заданной формуле и вывод их на экран в одну строку с заданием формата. Во втором цикле в переменной S происходит накапливание суммы элементов массива, имеющих нечетные номера. Определение нечетного номере элемента производится при помощи целочисленной операции mod.

Пример. Заполнить массив из пятнадцати элементов случайным образом целыми значениями, лежащими в диапазоне от -10 до 10. В этом массиве удалить k-й элемент массива.

Вывод S

program Delete;

Const n=15;

Var a : array[1..n] of integer;

i , k : integer;

begin

Randomize;

for i:=1 to n do

begin

a[i]:=random(21)-10;

Write(a[i]:8)

end;

Writeln;

Write(‘Введите номер элемента для удаления‘);

Readln(k);

for i:=k to n-1 do a[i]:=a[i+1];

a[n]:=0;

for i:=1 to n-1 do Write(a[i]:8)

end.

В программе организован цикл для ввода одномерного массива с использованием функции-генератора случайных чисел. Напомним, что случайные целые числа, принадлежащие отрезку [а,b], вычисляют по формуле a+random(b-a+1).

В операторе Readln(k) вводится номер удаляемого элемента массива. Под удаление элемента понимается его исключение из массива путем смещения всех следующих за ним элементов влево на одну позицию и присваивание последнему элементу массива значения ноль, если нет других оговорок. Поэтому в последнем цикле производится вывод элементов массива, исключая последний элемент.

Пример: Определить количество студентов в группе, имеющих рост выше среднего.

Program SredRost;

Uses crt;

Const n=25;

Var r : array[1..n] of real;

S: real; i, k: integer;

begin

ClrScr;

S:=0;

for i:=1 to n do

begin

Read(r[i]);

S:=S+r[i];

end;

S:=S/n;

k:=0;

for i:=1 to n do

begin

If r[i]>S then k:=k+1;

end;

Write(‘k=‘, k);

end.

Эта задача была ранее разобрана в Главе 3. Недостаток ввода одной и той же информации дважды устранили с использованием одномерного массива, элементами которого являются рост каждого студента r[i].

Пример: Найти минимальный и максимальный элементы последовательности а, состоящей из десяти элементов.

Program MinMax;

Uses crt;

Const n=10;

Type d=array[1..n] of integer;

Var a : d;

i, min, max: integer;

begin

ClrScr;

for i:=1 to n do

begin

Write(‘Введите’,i,’-й элемента массива‘);

Readln(a[i]);

end;

min:=a[1];

max:=min;

for i:=2 to n do

begin

If a[i]>max then max:=a[i];

If a[i]<min then min:=a[i];

end;

Write(‘max=‘,max, ‘min=’,min);

end.

Перед оператором ввода Readln(a[i]) выполняется оператор вывода Write(‘Введите’,I,’-й элемента массива‘), который представляет подсказку для пользователя при вводе исходной информации.

При i=1 на экране высветится: Введите 1-й элемент массива,

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

При i=2 на экране высветится: Введите 2-й элемент массива и так далее до конца выполнения цикла.

Присвоим переменной min и max значение первого элемента, и далее будем перебирать все элементы последовательности от 2 до n, сравнивая a[i] с max и с min. Если a[i] окажется больше, чем max, то max присваивается значение a[i]. Если a[i] окажется меньше, чем min, то min присваивается значение a[i]. По окончании цикла max примет значение наибольшего элемента последовательности, а min - наименьшего.

Пример: Заполнить двумерный массив случайным образом целыми значениями, лежащими в диапазоне от -25 до 50 и вывести его в стандартном виде (в виде матрицы).

Program Matrica;

Const n=5; m=6;

Var B: array[1..n,1..m] of integer;

i, j : integer;

begin

for i:=1 to n do

begin

for j:=1 to m do

begin

B[i,j]=random(76)-25;

Write(B[i,j]:4)

end;

Writeln

end;

end.

Решение этой задачи включает в себя: формирование элементов массива при помощи функции – генератора случайных чисел и вывод их в виде матрицы.

Индексы i и j определяют номер строки и столбца.

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

Пример: Найти количество ненулевых элементов вещественного массива А(12,10).

Начало

i = 1, 12, 1

j = 1, 10, 1

Ввод A[i,j]

+

A[i,j]0

_-

k = k+1

Вывод k

Конец

Program Kolvo;

Var a: array[1..12,1..10] of real;

i, j, k : integer ;

begin

for i:=1 to 12 do

for j:=1 to 10 do read (a[i,j]);

k:=0;

for i:=1 to 12 do

for j:=1 to 10 do

if a[i, j]<>0 then k:=k+1;

Write('Количество =', k)

end.

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

Пример: Дан массив C(15,55). Найти сумму положительных элементов в каждом столбце данного массива.

+

_-

Program stolbec;

Var C: array[1..15,1..55] of real;

i, j : integer ; S: real;

begin

for i:=1 to 15 do

for j:=1 to 55 do read(C[i, j]);

for j:=1 to 55 do

begin

S:=0;

for i:=1 to 15 do

if C[i , j]>0 then S:=S+C[i, j];

writeln(’ В’, j, ’-ом столбце сумма=:’, S)

end

end.

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

На втором этапе внешним циклом является цикл по индексу j (по столбцам). Тело внешнего цикла содержит следующие действия: задание нулевого значения суммы; выполнение внутреннего цикла от начального до конечного значения параметра i (по строкам) для подсчета суммы положительных элементов при неизменном значении параметра внешнего цикла; вывод значения суммы данного столбца. Затем j - параметр внешнего цикла изменяется на единицу, и опять от начала и до конца выполняется тело цикла.

Пример: Определить среднее арифметическое элементов побочной диагонали в заданном массиве А(8,8).

+

_-

Program Sred_ar;

Const n=8;

Var A: array[1..n,1..n] of integer;

i, j , S: integer ;

begin

S:=0; k:=0;

for i:=1 to n do

for j:=1 to n do

begin

Read(A[i, j])

if i+j< n+1 then

begin

S:=S+A[i, j];

k:=k+1;

end;

end;

Writeln(’Среднее арифметическое элементов над побочной диагональю’,

S/k:4:2)

end.

В переменной S будем накапливать сумму элементов, расположенных над побочной диагональю, а в переменной k подсчет количества этих элементов. После завершения цикла определяем среднее арифметическое по формуле S=S/k.

Пример: Сформировать квадратную матрицу порядка n по формуле . Составить одномерный массив S из положительных элементов главной диагонали введенной матрицы.

+

_-

Program Sred_ar;

Const n=10;

Var A: array[1..n,1..n] of real;

S: array[1..n*n] of real;

i, j , k: integer ;

begin

k:=0;

for i:=1 to n do

begin

for j:=1 to n do

begin

A[i, j]:=Sin((sqr(i)-sqr(j))/n);

Write(A[i, j]:6:2);

if (i=j) and (A[i, j]>0) then

begin

k:=k+1;

S[k]:= A[i,j]

end;

end;

Writeln;

end;

for i:=1 to k do Write(S[i]:6:2)

end.

Решение задачи содержит два этапа: вычисление элементов квадратной матрицы по формуле и создание нового одномерного массива из двумерного согласно заданному условию.

При описании массива необходимо указывать фиксированное количество компонент. Так как размерность нового одномерного массива заранее неизвестно, то в описании указывается максимально возможное количество элементов, которое не будет превышать размерности матрицы. А реальное количество элементов в новом массиве будет определяться переменной k.

4.6 СОРТИРОВКА ОДНОМЕРНОГО МАССИВА

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

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

Существует целый класс алгоритмов сортировки:

  • Линейная сортировка (сортировка методом прямого выбора)

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

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

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

  • Метод сортировки Шелла

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

  • Метод быстрой сортировки с разделением (К. Хора)

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

Рассмотрим фрагменты программ некоторых из перечисленных методов сортировки.