- •Методические указания
- •«Информатика»
- •Содержание
- •Введение
- •2 . Методические указания по выполнению контрольной работы
- •3. Цели и задачи выполнения контрольной работы
- •4. Общие требования к содержанию и оформлению контрольной работы
- •Задания к контрольным работам Контрольная работа № 1
- •Контрольная работа № 2 Линейные массивы
- •Справочные материалы для самостоятельной работы студентов Основные сведения о языке Паскаль
- •Правила языка
- •Оператор n
- •Программа:
- •Оператор
- •Одномерные массивы Описание массивов
- •Многомерные массивы
- •Рекомендуемая литература Основная литература
- •Дополнительная литература
Одномерные массивы Описание массивов
Массивы относятся к так называемым структурированным данным, то есть данным, которые составляют из других типов данных.
Массив – это формальное объединение нескольких однотипных объектов (чисел, символов, строк и т.п.), рассматриваемое как единое целое. Массив можно назвать совокупностью фиксированного числа одинаковых компонент, каждая из которых снабжается индексом, т.е., массив – это упорядоченное множество однотипных переменных (элементов массива), объединённых общим именем и отличающихся номерами (индексами). Массивы сходны с такими понятиями в математике, как векторы и матрицы.
Например, на метеостанции каждый час измеряется температура воздуха, и значения записываются в таблицу.
Время измерения, ч |
1 |
2 |
… |
23 |
24 |
Температура, ºC |
17 |
16 |
… |
18 |
17.5 |
Этот массив (таблица) содержит 24 элемента, пронумерованных от 1 до 24. Так, второй элемент массива имеет значение 16, а двадцать третий 18.
Примеры таких массивов есть не только в математике, Всем хорошо известна пушкинская строка: « И тридцать витязей прекрасных…». Имён витязей и их отличительных характеристик мы не знаем. Для нас все витязи могут выступать под одним именем «Дружина». Таким образом, если у простых переменных имя относится только к одной ячейке, то у массивов одно имя обозначает множество ячеек памяти, отличающихся номерами (индексами). Каждый массив характеризуется:
размерностью,
границами индексов по каждому измерению,
длиной.
Линейным (одномерным массивом) можно назвать совокупность одинаковых компонент, имеющих один индекс.
Описать массив можно либо в разделе переменных, либо с использованием описания нового типа. При описании массива необходимо указать:
имя массива,
из элементов, какого типа он состоит,
сколько элементов содержит массив,
как нумеруются (или индексируются элементы).
Описание массива в разделе описания переменных выглядит так:
var
имя_массива : array [тип индекса] of тип_элементов;
Здесь array, of– зарезервированные слова (массив, из).
Например:
a,b,c,d : array [integer] of integer;
Здесь определено 4 массива с именами a,b,c и d. Все они состоят из элементов типа Integer. Элементы нумеруются целыми числами от -32768 до 32767, так как типом индекса указан тип Integer. Как правило, для типа индекса используют тип диапазон (вырезку одного из базовых перечисляемых типов). Например
x1 : array [1..100] of real;
Элементы массива х1 имеют тип real и нумеруются целыми числами от 1 до 100 включительно. Нумеровать элементы массива можно не только числами, но и значениями любого другого перечисляемого типа, например, Char:
c1 : array [‘a’..’z’] of real;
Элементы массива с1 имеют тип real и индексируются буквами латинского алфавита.
Другой способ описания массивов — описание типа массива в разделе типов. Для перечисленных выше примеров это будет выглядеть так:
type
tmassiv1 = array [integer] of integer;
tmassiv2=array [1..100] of real;
tmass = array [‘a’..’z’] of real;
После этого типами tmassiv1, tmassiv2, tmass можно пользоваться как стандартными, то есть в разделе описания переменных описывать переменные этих типов:
var
a,b,c,d : tmassiv1;
x1 : tmassiv2;
c1 : tmass;
Действия над элементами массивов
Доступ (обращение) к отдельным элементам массива осуществляется путём указания имени переменной массива, за которым в квадратных скобках помещается значение индекса (порядкового номера) элемента. Примеры задания индекса: M[5] - непосредственно числом; M[k] - косвенно через переменную k; M[k1+5] - косвенно через выражение k1+5; M[Succ(i)] - косвенно через значение функции. Всем элементам одного массива можно присвоить значения элементов другого массива с помощью одного оператора присваивания, в том случае, когда массивы имеют идентичный тип. Так, если заданы следующие массивы:
var x, y: array [1 . . 10] of integer ;
z : array [1 . . 10] of integer;
то допустим следующий оператор присваивания:
X:=Y,
но недопустим оператор Z:=X, так как массивы X и Z неидентичных типов. В Паскале над массивами не определены операции отношения. Сравнивать массивы можно только поэлементно. К отдельным элементам массива можно применять стандартные процедуры и функции, предусмотренные в языке. Перечень стандартных допустимых подпрограмм зависит от типа элементов массива.
Например,
mas[2]:=34;
элементу массива mas с индексом 2 присваивается значение 34. Оператор
writeln(mas[2]);
выведет на экран значение хранящегося в элементе-ячейке №2 массива mas. Используя в качестве индекса переменную цикла "FOR ... TO ... DO" можно обратиться к каждому элементу массива поочереди. Так с помощью фрагмента программы
for i:=1 to 25 do mas[i]:=0;
всем элементом массива присваивается значение "0".
Использование массивов вместо одиночных переменных позволяет благодаря применению циклов "For ... To ... Do" существенно сэкономить время и объём программы. Это демонстрируется следующим примером.
Пример 1.
Дана последовательность вещественных чисел s1 ... s30. Организовать массив для хранения этих чисел. Определить сумму этих чисел.
program primer1;
uses crt;
type p=1..30;
var
m: array[p] of real; {описание массива}
i: p; {параметр цикла for}
s: real; {сумма элементов}
begin
clrscr;
for i:=1 to 30 do {заполнение массива}
begin
write('введите элемент последовательности n ',i);
readln(m[i])
end;
s:=0; {обнуление счётчика суммы}
for i:=1 to 30 do s:=s+m[i]; {вычисление суммы}
write('сумма элементов последовательности равна ', s);
readkey { пауза }
end.
Заполнение массивов
При работе с массивами необходимо заполнить их, то есть присвоить значение каждому элементу массива. Для заполнения массива x1 можно, например, использовать ввод с клавиатуры:
writeLn(‘Введите значение для элементов массива:’);
for i:=1 to 100 do
begin
write(‘x1[’,i,’]=’);
readln(x1[i])
end;
При отладке программы приходится вводить с клавиатуры много элементов массива. Чтобы избавиться от этой утомительной работы целесообразно заполнять массивы случайными числами. Для этого в начале программы один раз запускается датчик случайных чисел процедурой Randomize. Затем каждому элементу массива присваивается случайное значение с помощью функции Random. Использование функции Random может быть разнообразным. Если ее использовать с аргументом, например, x1[i]:=random(M), то она генерирует целое равномерно распределенное случайное число из отрезка [0,M-1], где М — целое положительное число. Если Random использована без аргументов x1[i]:=Random, то генерируется вещественное равномерно распределенное случайное число из отрезка [0,1). Например, заполнение массива случайными числами из отрезка [150,200), будет выглядеть так:
randomize; {инициализируем датчик}
for i:=1 to 100 do {для каждого элемента}
x1[i]:=150+50*random; {присваиваем случайное}
Поиск элементов, удовлетворяющих заданному условию
Зачастую приходится искать в неупорядоченном массиве элементы, которые удовлетворяют заданному условию. Например, условию положительности. Подсчитаем число положительных элементов массива
Следующая программа заполняет массив N целыми случайными числами от -100 до 100, определяет количество положительных элементов и выдаёт сообщение на экран.
program primer2;
uses crt;
type p=1..30; l=0..30;
var
m: array[p] of Integer; {jписание массива}
i,n: p; {параметр цикла for}
k: l; {счётчик положительных эл-ов}
begin
clrscr;
write(‘n=’);readln(n);
randomize; {инициализация датчика}
for i:=1 to n do {заполнение массива}
m[i]:=Random(201)-100;
k:=0; {обнуление счётчика п. эл-ов}
for i:=1 to n do
if m[i]>=0 then {условие положительности}
inc(k); {наращиваем на 1 счетчик}
if k=0 then
writeln(‘ в массиве положительных элементов нет’)
else
writeln('в массиве ',n,' положительных эл-ов');
readrkey; { пауза }
end.
Определение максимального элемента и его положения в массиве
Рассмотрим пример программы, которая заполняет вещественный массив случайными числами и определяет значение и индекс (номер) максимального элемента этого массива
program primer3;
uses crt;
type p=1..30;
var
m: array[p] of real; {описание массива}
i, imax, n: p; {параметр цикла for, номер макс. элемента, количество элементов}
max: real; {значение максимального элемента}
begin
clrscr;
write(‘n=’); readln(n);
randomize;
for i:=1 to n do
m[i]:=10*Random; {заполнение массива}
max:=m[1]; {допустим, что 1-й элемент - максимален}
imax:=1;
for i:=2 to n do {для всех остальных элементов}
if m[i]>max then {сравниваем с максимальным}
begin
max:=m[i];
imax=I
end;
writeln('максимальный элемент = ',max:5:2);
writeln('номер максимального элемента ',t);
readkey; { пауза }
end.
Второй вариант программы:
program primer3;
uses crt;
type p=1..30;
var
m: array[p] of real; {Описание массива}
i, imax n: p; {параметр цикла for, номер макс. элемента, количество элементов}
begin
clrscr;
write(‘n=’); readln(n);
Randomize;
for i:=1 to n do
m[i]:=10*random; {заполнение массива}
imax:=1; {допустим, что 1-й элемент - максимален}
for i:=2 to n do {для всех остальных элементов}
if m[i]>m[imax] then {сравниваем с максимальным}
imax:=i;
writeln('максимальный элемент = ',m[t]:5:2);
writeln('номер максимального элемента ',t);
readkey; { пауза }
end.
Упорядочивание (сортировка) массивов.
Задачи упорядочивания линейных и двумерных массивов возникают при оформлении статистических сводок, справочных материалов и т.д. Большинство финансовых документов, например, счета, подготовленные для рассылки, должны быть отсортированы (по фамилии, сумме и т.д.) для облегчения работы с ними. Список телефонов в случайном порядке практически бесполезен.
В большинстве случаев, массивы применяются для хранения большого количества однотипной информации, создания и организации баз и банков данных и т.д. Во многих случаях номер (индекс) элемента в массиве не играет большой роли. Важно именно его значение, т.е. сама информация.
Базы и банки данных, в свою очередь, необходимы не только для того, чтобы "складывать" в них информацию, но и для того, чтобы в любой момент была возможность удобного и быстрого доступа к ней. В обычном "не отсортированном" массиве информацию найти можно, но только способом последовательного перебора-просмотра всех его элементов, до тех пор, пока нужный элемент не будет обнаружен. Этот самый простой метод обладает только одним, но очень существенным недостатком - на поиск одного элемента уходит много времени. Все остальные методы поиска информации намного эффективнее, быстрее, но применяются только в упорядоченных, отсортированных массивах. Поэтому часто возникает задача об упорядочивании массива.
Сортировкой числового массива называют расположение его элементов в возрастающем (неубывающем) или убывающем (невозрастающем) по величине порядке. Сортировка символьного массива заключается в расположении элементов, например, по алфавиту или по длине строк.
Рассмотрим простой случай такой задачи: дан числовой массив x1, x2, ... xn, элементы которого попарно различны; требуется переставить элементы массива так, чтобы после перестановки они были упорядочены в порядке возрастания: x1 < x2 < ... < xn.
Существует множество алгоритмов решения этой задачи. Они могут существенно различаться между собой по основному параметру – быстродействию.
Сортировка с «возвратом в начало»
Последовательно, начиная с первого элемента, просматривается массив, и сравниваются пары, расположенных рядом чисел. В первой попавшейся паре, в которой не удовлетворяется условие возрастания, числа поменять местами. Перейти к пункту 2.
Проверить – все ли числа массива рассмотрены. Если не все, то перейти к пункту1, иначе к пункту3.
Печать упорядоченного массива.
program primer4;
uses crt;
type p=1..30;
mas=array[p] of real;
var a: mas; I, n:p ;m: real;
begin
clrscr;
write(‘n=’);
readln(n);
for i:=1 to n do
begin
write(‘a[‘,i,’]=’);
readln(a[I])
end;
i:=1;
while i<=n-1 do
If a[i]>a[i+1] then
begin
m:=a[i];
a[i]:=a[i+1];
a[i+1]:=m;
i:=1
end
else
i: =i+1;
writeln;
for i:=1 to n do
write(a[I]:7:2,’ ‘);
readkey
end.
Сортировки методом «без возврата в начало»
Этот метод ещё называют «сортировка простым обменом» или «метод пузырька». При этой сортировке массив каждый раз просматривается до конца, и сравниваются пары рядом стоящих элементов массива. При необходимости элементы меняются местами, и просмотр возобновляется с очередного элемента. По завершении цикла сравнений наибольший элемент массива передвигается на последнее место, а просмотр массива возобновляется с первого элемента при уменьшении на единицу количества просматриваемых элементов (до n-1 элемента), так как наибольший из оставшихся элементов после каждого просмотра будет оказываться в конце. Массив будет упорядочен до конца после просмотра, в котором участвуют только первый и второй элементы, следовательно, количество просмотров ограничено значением n-1. Этот алгоритм называют «метод пузырька» потому что при его реализации наибольшие и наименьшие элементы, как пузырьки, перемещаются («опускаются» или «поднимаются») в массиве (в его конец или начало).
program primer5;
uses crt;
type p=1.30;
mas=array[p] of real;
var a: mas; I, j, n:p ;m: real;
begin
clrscr;
write(‘n=’);
readln(n);
for i:=1 to n do
begin
write(‘a[‘,i,’]=’);
readln(a[i])
end;
for i:=1 to n-1 do
for j:=1 to n-I do
If a[j]>a[j+1] then
begin
m:=a[j];
a[j]:=a[j+1];
a[j+1]:=m
end;
writeln;
for I:=1 to n do
write(a[I]:7:2,’ ‘);
readkey
end.
Алгоритм сортировки перебором (прямого выбора)
Этот алгоритм заключается в поиске минимального (или максимального) элемента массива. Это выполняется сначала во всём массиве, затем в части массива, с каждым шагом уменьшающейся на один элемент. На место этого элемента и записывается найденный в шаге минимальный (максимальный) элемент. Для этого необходимо выполнить следующую последовательность действий:
1. Определить минимальный элемент массива;
2. Поменять его местами с первым элементом;
3. Определить минимальный элемент среди оставшихся элементов;
4. Поменять его местами со вторым элементом и т.д.;
Эта последовательность действий должна выполняться до тех пор, пока не будет определён последний минимальный элемент.
program primer6;
uses crt;
type p=1..30;
mas=array[p] of real;
var a: mas; I, j, n,k:p ;m: real;
begin
clrscr;
write(‘n=’);
readln(n);
for i:=1 to n do
begin
write(‘A[‘,i,’]=’);
readln(a[i])
end;
for i:=1 to n-1 do
Begin
k:=i;
For j:=i+1 to n do
If a[j]<a[k] then
k:=j;
m:=a[I];
a[i]:=a[k];
a[k]:=m
end;
writeln;
for I:=1 to n do
write(a[I]:7:2,’ ‘);
readkey
end.
Второй вариант программы.
program primer6;
uses crt;
type p=1..30;
mas=array[p] of real;
var a: mas; i, j, n,k:p ;m: real;
begin
clrscr;
write(‘n=’);
readln(n);
for i:=1 to n do
begin
write(‘a[‘,i,’]=’);
readln(a[i])
end;
for i:=1 to n-1 do
For j:=i+1 to n do
If a[j]<a[i] then
begin
m:=A[j];
a[j]:=a[i];
a[i]:=m
end;
writeln;
for i:=1 to n do
Write(a[i]:7:2,’ ‘);
Readkey
End.
Алгоритм сортировки простыми вставками
При этой сортировке последовательно перебирают элементы массива А1, А2,…,АN и каждый просматриваемый элемент Аi этой последовательности вставляют на подходящее место в уже упорядоченную последовательность А1,А 2 ,…, Аi-1. Место вставки просматриваемого элемента в упорядоченную последовательность определяется последовательным сравнением значения элемента Аi со значениями элементов предварительно упорядоченной подпоследовательности А1,…,Аi-1. Затем в найденном месте соседние элементы массива раздвигаются, освобождая место под элемент Аi.
program primer7;
uses crt;
type p=0..30;
mas=array[p] of real;
var a: mas; i, j, n:p ; b: real;
begin
clrscr;
write(‘n=’);
readln(n);
for i:=1 to n do
begin
write(‘a[‘,i,’=’);
readln(a[i])
end;
for i:=2 to n do
begin
b:=a[i]
a[0]:=b;
j:=i-1;
while b<a[j] do
begin
a[j+1]:=a[j];
j:=j-1
end;
a[j+1]:=b
end;
writeln;
for I:=1 to n do
write(a[I]:7:2,’ ‘);
readkey
end.
Алгоритм сортировки методом индексации
При этом алгоритме используют то, что оперируют с дополнительным массивом индексов. Меняют местами не сами элементы в исходном массиве, а меняют индексы у элементов массива.
program primer8;
uses crt;
type p=1.. 30;
mas=array[p] of real;
var b,a: mas; i, j, n, k:p ; min: real;
begin
clrscr;
write(‘n=’);
readln(n);
for i:=1 to n do
begin
write(‘a[‘,i,’]=’);
readln(a[i])
end;
for i:=1 to n do
begin
b[i]:=i;
for i:=n downto 1 do
for j:=1 to i-1 do
begin
c1:=b[j];
c2:=b[j+1];
If a[c1]>a[c2] then
begin
b[j]:=c2;
b[j+1]:=c1
end
end;
writeln;
for I:=1 to n do
write(a[I]:7:2,’ ‘);
readkey
end.
Алгоритм сортировки методом Д. Л. Шелла
Основная идея этого алгоритма заключается в том, чтобы вначале устранить массовый беспорядок в массиве, сравнивая, далеко отстоящие друг от друга элементы, и постепенно уменьшить этот интервал до единицы. Это означает, что на последних шагах сортировка сводится просто к перестановкам соседних элементов (если такие перестановки необходимы).
program primer9;
uses crt;
type p=1..30;
mas=array[p] of real;
var a: mas; i, j, n,k,c:p ;
begin
clrscr;
write(‘n=’);
readln(n);
for I:=1 to n do
begin
write(‘a[‘,i,’]=’);
readln(a[I])
end;
k:=n div 2; { вычисление шага}
while k>0 do
begin
for j:=n-k downto 1 do
begin
i:=j;
while i<=n-k do
begin
If a[i]>a[i+k] then
begin
c:=a[i];
a[i]:=a[i+k];
a[i+k]:=c
end;
i:=i+k
end
end;
k:=k div 2
end;
writeln;
for I:=1 to n do
write(a[I]:7:2,’ ‘);
readkey
end.
Существуют и другие методы сортировки массивов. Например, метод "быстрой" сортировки, предложенный К. Хоаром (C. Hoare), основан на разделении массива на два непустых непересекающихся подмножества элементов. При этом в одной части массива должны оказаться все элементы, которые не превосходят по значению некоторый предварительно выбранный элемент массива, а в другой части - все элементы, не меньшие его. Аналогично следует поступить с каждой из полученных групп (при этом элемент для разделения можно выбирать просто из "середины" группы). На определенном этапе массив окажется полностью отсортированным.
В подавляющем большинстве реальных случаев использование "быстрой" сортировки дает лучшие результаты по времени, чем все прочие методы.
Алгоритм сортировки слиянием фон Неймана, заключается в том, что каждая пара соседних элементов сливается в одну группу из двух элементов, (последняя группа может состоять из одного элемента). Каждая пара соседних двухэлементных групп сливается в одну четырёхэлементную группу и т.д. При каждом слиянии новая укрупнённая группа упорядочивается.
При алгоритме сортировки подсчётом выходной массив заполняется значениями –1. Затем для каждого элемента определяется его место в выходном массиве путём подсчёта количества элементов, строго меньших данного. Естественно, что все одинаковые элементы попадают на одну позицию, за которой следует ряд значений –1. После этого оставшиеся в выходном массиве позиции со значением –1 заполняются копией предыдущего значения.
При «хитрой» сортировке из массива путём однократного просмотра выбирается последовательность элементов, расположенных в порядке возрастания, переносится в выходной массив и заменятся во входном значением –1. Затем оставшиеся элементы включаются в полученную упорядоченную последовательность методом «погружения», когда очередной элемент путём ряда обменов «погружается» до требуемой позиции в уже упорядоченную часть массива.
Удаление элементов из массива и
вставка элементов в массив
К сожалению, Turbo Pascal не имеет средств для создания массивов переменной длины. Длина массива указывается на этапе создания программы при описании массива. В ходе выполнения программы длина массива меняться не может. Поэтому при необходимости работы с массивами переменной длины описывают массив заведомо большего размера. Вместе с тем описывают целую переменную, смысл которой — фактическая длина массива, то есть, размер используемой части массива. Хотя этот путь и нерационален, мы будем использовать его для работы с массивами переменной длины, чтобы отработать алгоритмы удаления и вставки элементов.
Чтобы удалить элемент с номером g из массива, необходимо каждый элемент, начиная с g+1 и до последнего, переместить на место предыдущего элемента и уменьшить на 1 размер массива. Описанный алгоритм реализуется следующим фрагментом программы:
…………………………
type p=1..10;
var
mas: array[p] of real; {описание массива}
i: p; {параметр цикла for}
n: p; {фактический размер массива}
…………………………
for i:=g to n-1 do mas[i]:=mas[i+1];
dec(n); {уменьшение n на 1}
…………………………
Для вставки элемента в массив на место с номером g необходимо предварительно освободить для него это место. Для этого, начиная с конца массива и до элемента с номером g, каждый элемент перемещается на следующее за ним место, и размер массива увеличивается на 1. Затем присваивается новое значение элементы с номером g:
…………………………
for i:=n downto g do
mas[i+1]:=mas[i];
mas[g]:=b;
Inc(n); {увеличение n на 1}
…………………………
