- •Глава 1
- •Свойства алгоритма
- •Словесный способ записи алгоритма.
- •Структурно-стилизованный способ записи алгоритма.
- •Программный способ записи алгоритма.
- •Графический способ записи алгоритма.
- •Циклическая структура с постусловием
- •Циклическая структура с предусловием
- •Циклическая структура с параметром
- •Глава 2
- •Символы разделители:
- •Зарезервированные слова
- •Стандартные идентификаторы
- •Стандартные константы
- •Операции div и mod
- •Стандартные функции
- •Правила написания арифметических выражений
- •Возведение в степень
- •Раздел описания меток
- •Раздел описания констант
- •Раздел описания переменных
- •Раздел определения типов данных
- •Перечисляемый тип
- •Интервальный тип
- •Раздел описания процедур и функций
- •Раздел var ?
- •Глава 3
- •Оператор присваивания
- •Оператор безусловного перехода goto
- •Оператор вызова процедуры
- •Пустой оператор
- •Составной оператор
- •Условные операторы
- •Операторы повтора
- •Глава 4
- •Линейная сортировка
- •Метод сортировки Шелла
- •Метод прямого обмена (пузырьковый метод)
- •Глава 5
- •Глава 6
- •Цветовая шкала
- •Стандартные стили заполнения
- •Стиль линии
- •Толщина линии
- •Построение прямоугольников
- •Построение дуг и окружностей
- •Глава 1 3
- •Глава 2 36
- •Глава 3 78
- •Глава 4 130
- •Глава 5 157
- •Глава 6 167
Глава 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 СОРТИРОВКА ОДНОМЕРНОГО МАССИВА
С ортировка – это процесс упорядочивания набора данных одного типа по возрастанию или убыванию значения какого-либо признака.
При сортировке элементы массива меняются местами таким образом, что их значения оказываются упорядоченными или по возрастанию, или по убыванию. Если в массиве есть одинаковые элементы, то говорят о сортировке по неубыванию или по невозрастанию.
Существует целый класс алгоритмов сортировки:
Линейная сортировка (сортировка методом прямого выбора)
Идея линейной сортировки по неубыванию заключается в том, чтобы, последовательно просматривая весь массив, отыскать наименьший элемент и поменять местами его с первым элементом. Затем просматриваются элементы массива, начиная со второго, снова находится наименьший, который меняется местами со вторым и т.д., пока не будет отсортирован весь массив.
Сортировка методом прямого обмена («пузырьковый» метод)
Метод основан на том, что весь массив просматривается с конца и в том случае, если из двух соседних элементов «нижний» элемент меньше, чем «верхний», элементы меняются местами. Таким образом самый меньший (самый «легкий») элемент оказывается ближе к началу массива («всплывает»). Отсюда и одно из названий метода - «пузырьковая» сортировка. Особенностью данного метода является сравнение, а затем, если нужно, и перестановка соседних элементов.
Метод сортировки Шелла
Основная идея алгоритма заключается в том, чтобы вначале устранить массовый беспорядок в массиве, сравнивая далеко отстоящие друг от друга элементы, и постепенно уменьшить этот интервал до единицы. На последних шагах сортировка сводится просто к перестановкам соседних элементов (если, конечно, такие перестановки необходимы).
Метод быстрой сортировки с разделением (К. Хора)
Работает быстрее. В основу алгоритма положен метод последовательного дробления массива на части и обмен элементами между частями. Алгоритм очень сложный и требует знания процедур и рекурсий.
Рассмотрим фрагменты программ некоторых из перечисленных методов сортировки.