Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

14-es / ЭС - Информатика (ИСФ) / умк_Спиридонов_Информатика_ч.1_2013

.pdf
Скачиваний:
32
Добавлен:
18.05.2015
Размер:
4.15 Mб
Скачать

2.8.3. Выборка элементов массива

Составить программу подсчета количества положительных элемен- тов массива, состоящего из 10 элементов.

Текст программы:

program mas3;

var k, i : integer;

a: array[1..10] of integer; begin

for i:=1 to 10 do begin

writeln(' Введите элемент массива'); readln(a[i]);

end;

writeln(' Элементы исходного массива'); for i:=1 tо 10 do

write (a[i],' '); writeln;

k:=0;

for i:=1 to 10 do

if a[i]>0 then k:=k+1; writeln(' Количество равно',k);

end.

Найти значение и номер наибольшего элемента в массиве из 10 це- лочисленных элементов.

Текст программы:

program mas4;

var n, m, i : integer;

a: array[1..10] of integer; begin

for i:=1 to 10 do begin

writeln('Введите элемент массива'); readln(a[i]);

end;

writeln('Элеметы исходного массива');

for i:=1 to 10 do

 

 

write(a[i]), ' ');

 

writeln;

 

 

m:=a[1]; n:= 1;

 

 

for i:=2 to 10 do

 

 

if a[i]>m then

 

 

begin

m:= a[i];

n:= i; end;

writeln('Максимальный элемент равен', m, 'и имеет порядковый номер', n);

end.

51

2.8.4. Сортировка массива

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

Сортировка методом прямого выбора. Алгоритм сортировки мас-

сива по возрастанию методом прямого выбора:

1.Просматривая массив от первого элемента, найти минимальный и поместить его на место первого элемента, а первый на место минимального.

2.Просматривая массив от второго элемента, найти минимальный и поместить его на место второго элемента, а второй на место минимального.

3.И так далее до последнего элемента.

Для демонстрации рассмотрим программу сортировки массива це- лых чисел по возрастанию (для контроля выполнения алгоритма програм- ма выводит массив после каждого обмена элементами).

program sort1;

Const size=5;

Var

a: array[1..size] of integer;

i: integer; {номер элемента, от которого ведется по-

иск минимального элемента}

min: integer; {номер минимального элемента в части массива от i до верхней границы массива}

j: integer; {номер элемента сравниваемого с минимальным} buf: integer; {буфер, используемый при обмене элемен-

тов массива}

k: integer;

begin

writeln(‘Сортировка массива’);

write(‘Введите через пробел’, size:3,’целых в одной строке и нажмите клавишу ввод’);

for k:=1 to size do read(a[k]); writeln(‘Сортировка’);

for i:=1 to size-1 do begin

min:=i;

for j:=i+1 to size do begin

52

if a[j]<a[min] then min:=j;

end;

buf:=a[i]; a[i]:=a[min]; a[min]:=buf;

for k:=1 to size do write(a[k],’ ‘);

writeln;

end; end.

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

program sort2; const size=5; Var

a: array[1..size] of integer; i: integer; {счетчик циклов} buf: integer;

k: integer; {текущий индекс элемента массива} begin

writeln(‘Сортировка массива методом пузырька’); write(‘Введите через пробел’, size:3,’целых в одной

строке и нажмите клавишу ввод’);

for k:=1 to size do read(a[k]); writeln(‘Сортировка’);

for i:=1 to size-1 do begin

for k:=1 to size-1 do begin

if a[k]>a[k+1] then begin buf:=a[k]; a[k]:=a[k+1]; a[k+1]:=buf; end;

end;

53

for k:=1 to size do write(a[k],’ ‘);

writeln;

end;

end.

2.8.5. Поиск в массиве

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

Рассмотрим программу поиска в массиве целых чисел. Перебор эле- ментов массива осуществляет инструкция REPEAT, в теле которой инст- рукция IF сравнивает текущий элемент массива с образцом и присваивает переменной naiden значение true, если текущий элемент равен образцу. Цикл завершается, если в массиве обнаружен элемент равный образцу, или если проверены все элементы массива. По завершении цикла по значению переменной found можно определить, успешен поиск или нет.

program poisk; var

massiv: array[1..10] of integer; {массив целых} obrazec: integer; {образец для поиска}

naiden: boolean; {признак совпадения с образцом} i: integer;

begin

writeln('Введите через пробел 10 целых элементов мас-

сива и нажмите клавишу ввода'); for i:=1 to 10 do read(massiv[i]);

write('Введите образец для поиска’); readln(obrazec);

naiden:=false;

i:=1; {проверяем с первого элемента массива} repeat

if massiv[i]=obrazec then naiden:=true else i:=i+1; until (i>10)or(naiden);

if naiden then writeln('Совпадение с элементом',i:3,'поиск завершен')

else writeln('Совпадений с образцом нет');

end.

54

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

Структура описания процедур и функций до некоторой степени по- хожа на структуру Паскаль-программы: у них также имеются заголовок, раздел описаний и исполняемая часть. Раздел описаний содержит те же подразделы, что и раздел описаний программы: описания констант, типов, меток, процедур, функций, переменных. Исполняемая часть содержит собственно операторы процедур.

Формат описания процедуры имеет вид:

procedure имя процедуры (формальные параметры) ;

раздел описаний процедуры

begin

исполняемая часть процедуры

end;

Формат описания функции:

function имя функции (формальные параметры): тип результата; раздел описаний функции

begin

исполняемая часть функции имя функции:=результат;

end;

Формальные параметры в заголовке процедур и функций записыва- ются в виде:

var имя параметра: имя типа;

и отделяются друг от друга точкой с запятой. Ключевое слово var может отсутствовать для входных параметров, а для выходных должен быть обя- зательно. Если параметры однотипны, то их имена можно перечислять че- рез запятую, указывая общее для них имя типа. При описании параметров можно использовать только стандартные имена типов либо имена типов, определенные с помощью команды type, вызывающей программы. Список формальных параметров может отсутствовать.

Вызов процедуры производится оператором, имеющим следующий формат:

имя процедуры (список фактических параметров);

Список фактических параметров это их перечисление через запя-

тую. При вызове фактические параметры как бы подставляются вместо

55

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

Вызов функции в Паскаль может производиться аналогичным спосо- бом, кроме того, имеется возможность осуществить вызов внутри какого- либо выражения. В частности, имя функции может стоять в правой части оператора присваивании, в разделе условий оператора if и т.д.

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

имя функции : = результат;

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

количество фактических параметров должно совпадать с количе- ством формальных;

соответствующие фактические и формальные параметры должны совпадать по порядку следования и по типу.

Процедуры и функции должны обладать определенной независимо- стью в смысле использования переменных, типов и констант. В связи

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

Глобальные это те константы, типы и переменные, которые объяв- лены в программе вне описания процедуры и функции и до их описания. Они доступны вызывающей программе и вызываемой подпрограмме.

Локальные константы, типы и переменные существуют только внут- ри подпрограммы, в которой они описаны через разделы объявлений или через список формальных параметров. Они доступны только подпрограм- ме, в которой они описаны.

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

var x,y,m,n : integer;

procedure MaxNumber (a,b: integer; var max: integer);

{в заголовке процедуры a,b – входные параметры, max – выход-

ной параметр};

begin {начало процедуры}

if a>b then max := a еlse max := b;

56

end;{конец процедуры}

begin {начало основной программы}

write ('Введите х,у ');

readln(x,y);

 

MaxNumber(x,y,m);

{формальный параметр a получает

значение х, b – значение y при вызове процедуры, m – значение результата из процедуры через параметр max};

MaxNumber(2,x+y,n);

writeln('m=',m,'n=',n);

end. {Конец основной программы}

Аналогично задачу, но уже с использованием функций, можно ре- шить так:

var

x,y,m,n :

integer;

 

function MaxNumber(a,b:

integer) : integer;

var

max: integer;

 

begin

{начало функции}

if a>b then

max := a

else max := b;

MaxNumber := max;

{имя функции получает значение результата целого типа}; end; {конец функции}

begin {начало основной программы} write('Введите х,у '); readln(x,y);

m := MaxNumber(x,y);

{в основной программе результат функции копируется в перемен- ную m};

n := MaxNumber(2, x+y);

writeln('m=',m,'n=',n);

end.

Рекурсивные подпрограммы. Рекурсия это способ организации вычислительного процесса, при котором подпрограмма обращается сама к себе, но с более «простыми» параметрами (измененными). Пример вычис- ления факториала числа (N! = N (N-1)!) c рекурсивным вызовом функции:

program rec1;

function fact (n : word) : word;

begin if n = 0 then fact := 1 else fact := n * fact (n- 1); end;

begin

write(‘Введите число ‘); readln(n); write(‘ Фасториал чис- ла ‘,n,’равен: ‘,fact(n))

end.

57

В практических задачах глубина рекурсивных вызовов должна быть конечна и невелика. Большая глубина рекурсивных вызовов приводит к переполнению стека. Кроме того, подобно операторам цикла, рекурсив- ные вызовы могут приводить к «зацикливанию». Для того чтобы избежать этого, в теле процедуры или функции должно быть некоторое управляю- щее условие с ветвью не содержащей рекурсивный вызов. Эта ветвь будет определять ограничение рекурсии (граничное условие).

Рекурсивные процедуры эффективны при работе со сложными дина- мическими структурами данных: списками, деревьями, графами.

2.10.Работа с двумерными массивами

2.10.1.Действия над элементами массива

При работе с двумерным массивом указываются два индекса, напри- мер B[4,4]. Индексированные элементы массива называются индексными переменными и могут быть использованы так же, как и простые перемен- ные. Например, они могут находиться в выражениях в качестве операндов, использоваться в операторах for, while, repeat, входить в качестве па- раметров в операторы read, readln, write, writeln; им можно при- сваивать любые значения, соответствующие их типу.

Копированием массивов называется присвоение значений всех эле- ментов одного массива всем соответствующим элементам другого масси- ва. Копирование можно выполнить одним оператором присваивания, на- пример A:=B, если массивы идентичны по структуре, или с помощью оператора for поэлементно:

For i:=1 to 5 do

For j:=1 to 7 do

A[i,j]:=В[i,j];

2.10.2. Действия над идентичными двумерными массивами

Выражение

Результат

А=В

True, если значение каждого элемента массива А равно со-

 

ответствующему значению элемента массива В.

А<>В

True, если хотя бы одно значение элемента массива А не

 

равно значению соответствующего элемента массива В.

А:=В

Все значения элементов В присваиваются соответствующим

 

элементам массива А. Значения элементов массива В оста-

 

ются неизменны.

58

2.10.3. Использование процедуры ввода и процедуры вывода элементов двухмерного массива

program

P_r_i_m_e_r_2;

 

const M = 2; { Количество строк в массиве

}

 

N =

3; { Количество столбцов в массиве }

type

T = Array [1..M,1..N] of Integer;

 

var

A : T;

 

 

procedure Wwod_Mass

(var S: T);

 

{Процедура ввода с клавиатуры элементов массива }

{процедура с параметрами}

{S - параметр, вызываемый по адресу}

var i,j: Integer; begin

WriteLn ('Введите массив: ');

For i:=1 to M do

For j:=1 to N do

begin Write ('Введите S[',i,',',j, ']: '); ReadLn (S[i,j]) end

END;

procedure Wywod_Mass (S:

T);

 

{ Процедура

вывода на

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

{ процедура

с параметрами

}

{ S - параметр, вызываемый по значению

}

var i,j: Integer;

 

 

BEGIN

 

 

 

WriteLn ('Вот Ваш массив: ');

 

For i:=1

to M do

 

 

begin

For j:=1

to N do Write (S[i,j],' ');

WriteLn end end;

BEGIN

Wwod_Mass (A);{Вызов процедуры ввода элементов массива} Wywod_Mass(A){Вызов процедуры вывода элементов массива}

end.

2.11. Файловый тип данных

Описание типа Var <имя файловой переменной>: file of <Имя базо- вого типа (типа элементов файла)>

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

59

в ОС, – физическое имя. Установление связи «логическое имя физиче- ское имя» выполняется специальной процедурой (Assign). Одно логиче- ское имя можно связывать в разное время с разными физическими, а это означает, что программу можно написать так, что ее не надо будет переде- лывать при смене имени файла в ОС или при работе с другим файлом.

Операции с файлами реализуются обращением к стандартным про- цедурам:

Assign(F, Связывает логическое имя файла F с его физическим именем

FName) FName

Reset(F) Открывает файл F для ввода Rewrite(F) Открывает файл F для вывода Close(F) Закрывает файл F

Read(F,R) Чтение элемента файла F в переменную R Write(F,R) Запись элемента файла А из переменной R Eof(F) Возвращает булевское значение "Конец файла"

Eof(F) Возвращает булевское значение "Конец файла" для файла F Eoln(F) Возвращает булевское значение "Конец строки" для файла F

Рассмотрим пример, иллюстрирующий работу с текстовым файлом. Пусть требуется оценить объем текста рукописи, записанного на диск в так называемых издательских листах, которые вмещают по 40 000 символов. В программе реализуем идею подсчета общего количества символов в тек- сте рукописи, пока не дойдем до конца файла, а затем при выводе ответа накопленное количество поделим на 40 000.

program Rukopis; var FTxt: Text;

s: String; sum: LongInt;

begin

Write('Введите имя файла: '); Readln(s); Assign(FTxt, s); Reset(FTxt);

Sum := 0;

while not Eof(FTxt) do begin

Readln(FTxt, s); Inc(sum, Length(s));

end;

Close(FTxt);

WriteLn('Объем = ', sum/40000:6:2,' издат. листов'); end.

60