лекция 4.pptx
- Количество слайдов: 23
МАССИВЫ
1. Понятие массива Достаточно часто возникает задача многократной обработки какой-то последовательности данных. Для того, чтобы облегчить Вам решение такого рода задач, существует тип данных, называемый МАССИВОМ. В общем случае, МАССИВ - это УПОРЯДОЧЕННАЯ последовательность данных ОДНОГО ТИПА. В памяти компьютера массив можно представить в виде последовательности блоков памяти, имеющих одно имя, и отличающихся каким-то признаком (назовем этот признак "индексом" или "порядковым номером"). Например, массив с именем DAY, состоящий из 16 элементов, представляется следующим образом: DAY - имя массива - номер Элемента Доступ к каждому элементу массива осуществляется по его индексу (порядковому номеру). Например, 5 -ый элемент массива DAY в программе записывается как DAY[5], 7 -ой - как DAY[7] и т. д. Обратите внимание на то, что индексы указываются после имени массива в КВАДРАТНЫХ скобках. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2. Описание массива. Прежде, чем работать с массивом, его нужно описать, т. е. включить в блок Var такую запись: <Имя> : array[<первый_элем>. . <последн_элем>] of <Тип> Например, строка var Mas : array[1. . 17] of Real; описывает массив из 17 элементов, имеющих порядковые номера (индексы) с 1, 2, . . . 17, а строка Var Mas 1 : array[0. . 15] of Integer; Описывает массив из 16 целых чисел с номерами 0, 1, . . . 15. В общем случае в языке Pascal в качестве индексов может выступать последовательность элементов любого перечислимого типа (т. е. такого типа данных, для каждого элемента которого известен предыдущий и/или последующий. Под такой тип явно не подходит тип REAL (какое число предшествует числу 1. 2? ) и тип String). Конечно, чаще всего используются числовые индексы.
Рассмотрим несколько примеров описания массивов, имеющих индексы, отличные от числовых: var sign: array['a'. . 'z'] of byte; а 1: array[0. . 15] of real; . . . Как уже отмечалось, обращение к отдельному элементу массива происходит так же, как и к элементу строки: после имени массива в квадратных скобках указывается номер нужного элемента. Например, запись a: =Mas[11] означает, что переменной a будет присвоено значение, взятое из 11 -го элемента массива Mas, запись a : = Mas[n] означает, что следует взять элемент массива Mas с номером, хранящимся в пере. Менной n, и занести значение этого элемента в переменную a. И, наконец, Mas[3]: =5; означает, что 5 -ому элементу массива присвоено значение 5. Обращение к элементу массива, имеющего нечисловой индекс, осуществляется аналогично: m: =sign['f']; sportsman[girl]: =12. 5; words['ж']: ='э';
3. Алгоритмы работы с массивами. Задача 1. Составить программу, в которой вводится произвольный набор из 15 целых чисел и выводится на экран в обратном порядке. Текст программы: Program Example 1; Var Mas : array[1. . 15] of Integer; i : Integer; begin Write. Ln('Введите 15 чисел'); For i: =1 to 15 do begin Write('Число ', i, ' = '); Read. Ln(Mas[i]); end; Write. Ln('Вот они в обратном порядке'); For i: =15 downto 1 do Write(Mas[i], ' '); Read. Ln; end.
Задача 2. Имеется какой-либо раствор, состоящий из заданного числа компонентов (например, французские духи состоят не менее чем из 50 компонентов). Определить процентное содержание каждой из компонент в растворе, если известен лишь вес каждой компоненты. Пояснение к решению. Задача решается достаточно просто: следует определить общий вес всей смеси (обозначим его Sum), а затем вес каждой. Компоненты поделим на Sum и умножим на 100 - и получит процентное содержание каждой компоненты в растворе. Если обозначить процентное содержание i-ой компоненты за Pi, а вес компоненты Vi, то формула определения процентного содержания i-ой компоненты раствора будет выглядеть следующим образом: Vi Pi= ---- *100 Sum
Текст программы: Program Example 2; Var V : array[1. . 50] of Real; Sum : Real; i, n : Integer; begin Sum : = 0; Write. Ln('Сколько компонентов вошло в смесь (не более 50)? '); Read. Ln(n); Write. Ln('Вводите массы, нажимая
Задача 3. Для заданной функции вычислить массив n ее значений в Равностоящих точках интервала [a, b]. Вывести на экран таблицу функций. Построить новый массив А в котором Y 1(i)= Y(i-1), т. е. в Y 1 записывается элемент из Y, но с номером на 1 меньшим. Program Function; var X, Y: array [0. . 20] of real; Y 1: array [1. . 20] of real; {ограниченный тип} n, i: integer; a, b, h: real; begin writeln('Введите начальное значение интервала а'); readln(a); writeln('Введите конечное значение интервала b'); readln(b); writeln('Введите количество разбиений интервала n, число не большее 20'); readln(n);
h: =(b-a)/n; {шаг разбиения х} for i: =0 to n do {построение массивов X и Y} begin x[i]: =a+i*h; y[i]: =2*sqr(x[i]); Writeln('x=', x[i]: 0: 2, 'y=', y[i]: 0: 2); end; for i: =1 to n do {построение массива Y 1} begin y 1[i]: =y[i-1]; Writeln('y 1[', i, ']=', y 1[i]: 0: 2); end. Задача 4. Составьте программу определения частоты использования английских букв в введенном тексте. Пояснение к решению. Задача достаточно проста: достаточно сосчитать общее количество букв в тексте, затем сосчитать количество букв а, b, . . . , z, а затем определить процентное содержание каждой из этих букв в тексте.
Текст программы: Program Chastota; Const signs=['a'. . 'z']; {это - множеств русских букв} Var speed: array['a'. . 'z'] of real; i: byte; c: char; speech: string; begin for c: ='a' to 'z' do speed[c]: =0; {начальные значения количества каждой из букв} Write. Ln('Введите текст: '); Read. Ln(speech); For i: =1 to length(speech) do if speech[i] in signs then speed[speech[i]]: =speed[speech[i]]+1; {После выполнения этого цикла в массиве speed будет храниться количество каждой из английских букв, имеющейся в данном тексте} {Теперь осталось вычислить общее количество букв в тексте без разделителей! И определить частоту использования букв. Выполните это самостоятельно} end.
Строковые массивы. Алгоритмы поиска 1. Мы не оговаривали специально, что массивы могут состоять не только из чисел, но и из символьных строк. На этой лекции мы разберем несколько типичных задач, связанных с обработкой строковых массивов. Описание такого массива в программе строится по общим правилам: <Имя_массива> : array[
Размеры массивов удобно предусмотреть достаточно большими "с запасом", а сколько будет введено пациентов каждый раз будет определяться в процессе работы: как только все данные исчерпаны, вместо ввода фамилии мы будем просто нажимать клавишу
while F <> '' do begin i : = i+1; { номер вводимой записи } Fam[i] : = F; { занесение фамилии в массив } Write('Год рождения: '); readln(God[i]); { ввод года рождения } Write('Диагноз : '); readln(Diag[i]); { ввод диагноза } write('Фамилия : '); readln(F); { ввод следующей фамилии } end; { ============================} begin { тело программы} end.
3. Следующая задача: среди имеющихся данных отыскать пациента с заданной фамилией и вывести на экран его диагноз. Идея решения заключается в том, чтобы просмотреть последовательно весь массив фамилий и, отыскав нужную (совпадающую с введенной), напечатать элемент массива диагнозов, имеющий тот же номер. Решение этой задачи можно также оформить в виде отдельной процедуры: Program Hospital; Const N = 100; Var Fam : array[1. . N] of String[20]; God : array[1. . N] of Integer; Diag : array[1. . N] of String[20]; Procedure Poisk; Var F : String[20]; i : Integer;
begin write('Введите фамилию: ' ); readln(F); i: =1; while (i
Процедура двоичного поиска: Program Example; Const N = 100; Var Fam : array[1. . N] of String[20]; God : array[1. . N] of Integer; Diag : array[1. . N] of String[20]; Procedure Poisk 2; Var F : String[20]; i 1, i 2, k, pr : Integer; begin pr : = 0; writeln('Введите фамилию' ); readln(F); i 1 : = 1; { начало } i 2 : = N; { и конец участка поиска } while i 1 < i 2 do { пока начало и конец участка поиска не слились }
begin k : = trunc((i 1+i 2)/2); { середина участка поиска } if Fam[k] = F { пациент найден } then begin writeln(Diag[k]); { вывод диагноза } pr : = 1; { установка признака того, что пациент найден} end else if F < Fam[k] { если нужная фамилия находится в первой половине списка, } then i 2 : = k-1 { то отбрасывается вторая половина, } else i 1 : = k+1; { в противном случае отбрасывается первая. } end; if pr = 0 { ни разу не выполнилось условие Fam[i] = F } then writeln('Такой пациент отсутствует'); end; { ============================ } begin { головная программа} end.
Двумерные и многомерные массивы Организация данных в виде массивов помогает нам решать многие задачи. Вот еще одна: разработать программу, обслуживающую шахматный турнир. Мы уже решали похожую "спортивную" задачу о конькобежных соревнованиях. Теперь нужно понять, чем отличается от них турнир по шахматам (с точки зрения организации данных). В одиночных соревнованиях каждый участник имеет один результат, поэтому данные о результатах соревнований удобно хранить в знакомых нам массивах. Игровой турнир предполагает встречи участников друг с другом, при этом каждый участник имеет столько результатов, со сколькими соперниками он встречался. Обычно результаты турниров заносятся в турнирные таблицы. Средством обработки таких таблиц в языках программирования служат двумерные массивы.
1. Описание двумерного массива В языке паскаль описание двумерного массива записывается так: <Имя_массива> : array[
Program Transp; {const A: array [1. . 2, 1. . 3] of integer=((2, 1, 5)(3, 4, 1)); } var A: array [1. . 2, 1. . 3] of integer; At: array [1. . 3, 1. . 2] of integer; j, i: integer; begin writeln('Введите элементы массива после каждого нажимая "ввод" '); for i: =1 to 2 do {количество строк} for j: =1 to 3 do {количество столбцов} begin readln(a[i, j]); At[j, i]: =a[i, j]; {транспонирование} end; {печать массива At} writeln('Транспонированный массив'); for i: =1 to 3 do {количество строк} begin wrireln; for j: =1 to 2 do write(At[i, j]) {количество столбцов} end; end.
Результат на экране: 23 14 51 Пр. 2. Турнирную таблицу для N участников удобно хранить в двумерном массиве N x N типа Real, т. к. результатом шахматной партии для каждого участника может быть победа (1 очко), поражение (0 очков) или ничья (0. 5 очка). Вот описание таблицы: Tab : array[1. . N, 1. . N] of Real. Для простоты не будем пока рассматривать фамилии участников, а будем различать их по номерам. Вводить результаты встреч будем в таком виде: номер первого участника, номер второго участника, результат первого участника (количество очков). Понятно, что одна встреча приводит к заполнению сразу двух элементов таблицы. Так будет выглядеть фрагмент программы, предназначенный для ввода результата одной встречи: writeln('Введите номера участников встречи'); readln(n 1, n 2); writeln('Сколько очков у участника ', n 1, ' ? '); readln(Tab[n 1, n 2]); Tab[n 2, n 1] : = 1 -Tab[n 1, n 2];
Эти действия нужно повторять столько раз, сколько встреч состоится в турнире. Если все запланированные встречи состоятся, то их количество можно сосчитать по формуле n(n-1) - подумайте, почему. Однако, может случиться, что по каким-то причинам часть встреч не состоится, а какие-то будут сыграны дважды. Поэтому удобнее как-то обозначить окончание ввода данных в программе, например, после каждой встречи выяснять, будут ли еще вводиться данные. Вот фрагмент программы, предназначенный для ввода результатов всех встреч турнира: kon : = 'Д'; while kon <> 'Н' do begin writeln('Введите номера участников встречи'); readln(n 1, n 2); writeln('Сколько очков у участника ', n 1, ' ? '); readln(Tab[n 1, n 2]); Tab[n 2, n 1] : = 1 -Tab[n 1, n 2]; writeln('Будут ли еще встречи ? (Д/Н)'); readln(kon); end;
5. По окончании турнира нужно вывести турнирную таблицу на экран: for i : = 1 to N do begin for k : = 1 to N do write(Tab[i, k]: 3: 1); writeln; end; 6. Бывают задачи, в которых данные удобно хранить в виде трехмерного (и даже четырех- и более -мерного) массива. Например, результат встречи в футбольном турнире представляет собой не одно, а три числа - количество забитых и пропущенных мячей и количество очков (2 - победа, 0 - поражение, 1 - ничья). Такую таблицу удобно заносить в массив Football : array[1. . N, 1. . 3] of Integer; Элемент Football[3, 5, 2] содержит информацию о количестве мячей, пропущенных 3 -й командой в матче с 5 -й командой. Поразмышляйте самостоятельно над процедурой ввода результатов футбольного турнира.