В этом примере множества s1 и s2 эквивалентны, а множество s3 включено в s2 и s1.
Над множествами определены следующие операции:
* – пересечение множеств; результат содержит элементы, общие для обоих множеств; например,
s4*s6 содержит [3, 6], s4*s5 – пустое множество;
+ – объединение множеств; результат содержит элементы первого множества, дополненные недостающими элементами из второго множества:
s4+s5 содержит [0,1,2,3,4,5,6]; s5+s6 содержит [3, 4, 5, 6, 7, 8, 9];
– – разность множеств; результат содержит элементы из первого множества, которые не принадлежат второму:
s6–s5 содержит [3,6,7,8,9]; s4–s5содержит [0,1, 2, 3, 6];
= – проверка эквивалентности; возвращает True, если оба множества эквивалентны;
<> проверка неэквивалентности; возвращает True, если оба множества неэквивалентны;
<= проверка вхождения; возвращает True, если первое множество включено во второе; например, условие s3<=s1 имеет значение True;
>= – проверка вхождения; возвращает True, если второе множество включено в первое;
in – проверка принадлежности; в этой бинарной операции первый элемент – выражение, а второй – множество одного и того же типа; возвращает True, если выражение имеет значение, принадлежащее множеству:
3 in s6 возвращает True; 2*2in s1 возвращает False.
Пример. Реализуем алгоритм выделения из N натуральных чисел всех простых чисел. [Простыми называются целые числа, которые не делятся без остатка на любые другие целые числа, кроме 1 и самого себя. К простым относятся 1, 2, 3, 5, 7, 11, 13 и т. д.] В его основе лежит прием, известный под названием “решето Эратосфена”. В соответствии с этим алгоритмом вначале формируется множество BeginSet, состоящее из всех целых чисел в диапазоне от 2 до N. В множество PrimerSet (оно будет содержать искомые простые числа) помещается 1. Затем циклически повторяются следующие действия:
· взять из BeginSet первое входящее в него число Next и поместить его в PrimerSet;
· удалить из BeginSet число Next и все другие числа, кратные ему, т.е. 2*Next, 3*Next и т. д.
Цикл повторяется до тех пор, пока множество BeginSet не станет пустым.
Эту программу нельзя использовать для произвольного N, так как в любом множестве не может быть больше 256 элементов.
N = 255; { Количество элементов исходного множества}
{ Цикл удаления из исходного множества непростых чисел}
while kr_Next <= N do
BeginSet:= BeginSet –[kr_Next];
kr_Next:=kr_Next+Next{Следующее кратное}
PrimerSet:=PrimerSet+[next];
Repeat{получение следующего простого числа – первого не вычеркнутого из исходного множества}
Inc(Next)
until (Next in BeginSet)or (Next > N)
end;{конец основного цикла}
{Вывод результата}
fori := 1toN do
ifi in PrimerSetthenwriteln(i:8);
writeln
6.3. Строки
Строка представляет собой особую форму одномерного массива символов (Array [0..N] of Char), которая имеет существенное отличие. Массив символов имеет фиксированную длину (количество элементов), которая определяется при описании. Строка имеет две разновидности длины: общая длина строки, которая характеризует размер памяти, выделяемой строке при описании, и текущая длина строки (меньше или равна общей длине), которая показывает количество символов строки в каждый конкретный момент времени.
Текущая длина строки указывается в нулевом (с индексом 0) элементе строки. Такой способ определения строки реализуется в виде предопределенного типа String.
var S:string[12];
…
S:=’BORLAND’;
…
Символ с кодом 7
B
O
R
L
A
N
D
Фиксированная общая длина строки =12. Текущая длина строки =7.
Определяемая при описании общая длина строки указывается в [ ]. Если длина не указывается, то по умолчанию принимается максимальная длина =255 символам. Например,
Var S1: String[10];
S2: String[128];
S3: String;
К любому символу в строке можно обратиться как к элементу одномерного массива Array [0..N] of Char. Например:
Const s = ‘Turbo Pascal’;
...
writeln(s[5]); {выводится символ «о»}
К строкам можно применять операцию «+» – сцепление, например:
s1:=’Turbo’; s2:=’Pascal’;
s3 := s1+’ ’+s2; {s3 содержит «Turbo Pascal»}
Операции отношения =, <>, <=, >=, <, > выполняются над двумя строками посимвольно, слева направо с учетом внутренней кодировки символов. Если одна строка меньше другой по длине, недостающие символы короткой строки заменяются значением символа с кодом 0.
Пример.Следующие операции отношения дадут значение True:
‘A’ > ‘1’
‘Turbo’ < ‘Turbo Pascal’
Для работы со строками типа String используются следующие процедуры и функции (модуль System):
Cоncat(S1, [S2, …, Sn]) – функция типа String; возвращает строку представляющую собой конкатенацию (сцепление) строк-параметров S1, [S2, …, Sn]. Если длина результирующей строки превышает 255 символов, то она усекается до 255 символов.
s3 := Concat(s1, ‘ ’, s2);
Copy(S, Index, Count) – функция типа String; возвращает копию подстроки, число символов которой соответствует параметру Count (тип Integer), из заданной строки S, начиная с символа строки S с индексом, заданным параметром Index (тип Integer).
D := Copy(S3, 7, 6); {D примет значение «Pascal»}
Delete(S, Index, Count) – процедура; удаляет Count символов из строки S, начиная с символа с номером Index.
s:=’Turbo Pascal’;
delete(s,6,7); {s примет значение «Turbo»}
Insert(S1, S, Index) – процедура; вставляет подстроку S1 в строку S, начиная с символа с номером Index.
Length(S) – функция типа Integer; возвращает текущую длину строки S.
L := Length(S);
Pos(S1, S) – функция типа Integer; производит поиск первого вхождения подстроки S1 в строку S и возвращает номер позиции, с которой она начинается; если подстрока не найдена, возвращается 0.
s3:=’Turbo Pascal’; s1:=’Pas’;
i:=Pos(s1,s3); {i примет значение 7}
Str(X, S) – процедура; преобразует число X любого вещественного или целого типов в строку символов S.
Str(pi:6:2,s1) {s1 примет значение ’3.14’}
Val(S, X, Code) – процедура; преобразует строку символов S во внутреннее представление целой или вещественной переменной X, которое определяется типом этой переменной; параметр Code содержит ноль, если преобразование прошло успешно, и тогда в X помещается результат преобразования, в противном случае Code содержит номер позиции в строке S, где обнаружен ошибочный символ, и в этом случае содержимое X не меняется. Пробелы в строке S должны отсутствовать.
Пример. Заменить в заданной строке все вхождения подстроки ‘da’ на ‘net’.
Program stroki;
var s: string; k: integer;
begin
writeln(‘Vvedite stroku ’);
readln(s);
while pos(‘da’,s)<>0 do
begin
k:=pos(‘da’,s);
delete(s, k, 2);
insert(‘net’, s, k);
end;
writeln(‘Poluchili stroku ’,s);
readln;
end.
6.4. Файлы
У понятия файла есть две стороны.
С одной стороны, файл – это именованная область внешней памяти ПК (жесткого диска, дискеты), содержащая какую-либо информацию. Файл в таком понимании называют физическим файлом.
С другой стороны, файл – это одна из многих структур данных, используемых в программировании. Файл в таком понимании называют логическим файлом. В программах логические файлы представляются файловыми переменными определенного типа.
Файловый тип или переменную файлового типа можно задать одним из трех способов, который определяется тип файла (типизированный, текстовый или нетипизированный):
VAR
<имя переменной> = Text; {текстовые файлы}
<имя перемен.>=File of <тип данных>; {типизированные файлы}
<имя перемен.> = File; {нетипизированные файлы}
Здесь <имя файл.переменной> – правильный идентификатор, file,of – зарезервированные слова (файл, из), text – имя стандартного типа текстовых файлов, <тип> – любой тип, кроме файлового.
Например,
Type
Product = Record
name: String;
cost: LongInt;
End;
Var
f1: File of Char;
f2: Text;
f3: File;
f4: File of Product;
Вид файла определяет способ хранения информации в файле. При объявлении уже существующих файлов программист должен сам следить за соответствием вида объявления характеру файла.
Длина файла никак не оговаривается при его объявлении, может изменяться в процессе выполнения программы и ограничивается только емкостью устройств внешней памяти.
Нумерация элементов в файле выполняется слева направо начиная с нуля (кроме текстовых файлов). Количество элементов в файле в каждый момент времени неизвестно, но известно, что в конце файла располагается специальный символ конца файла Eof (End of File).
Любой программе доступны два предварительно объявленных текстовых файла со стандартными файловыми переменными: Input – для чтения данных с клавиатуры, Output – для вывода на экран.
Любые другие файлы становятся доступны программе только после выполнения особой процедуры открытия файла. Эта процедура заключается в связывании ранее объявленной файловой переменной с именем существующего или вновь создаваемого файла, а также в указании направления обмена информацией (инициация файла): чтение из файла или запись в него.
Assign(<файл.переменная>,<имя файла>);
В результате обращения к стандартной процедуре Assignфайловая переменная связывается с именем файла
Например,
Assign(f3, ‘d:\dir\subdir\res.txt’);
Если имя файла задается в виде пустой строки, например, Assign(f1,‘’); то в зависимости от направления обмена данными файловая переменная связывается со стандартным файлом Input или Output.
Инициировать файл – означает открыть файла с указанием направления передачи данных: для чтения, для записи, а также для чтения и записи одновременно.
Процедуры и функции для работы с файлами:
Reset(<файловая переменная>);
Файл инициируется для чтения. При выполнении этой процедуры дисковый файл подготавливается к чтению информации. В результате специальная переменная-указатель, связанная с этим файлом, будет указывать на начало файла, т.е. на компонент с порядковым номером 0.
Если файл – текстовый, то он будет доступен только для чтения, а если типизированный, то он будет открыт и для чтения и для записи.
Rewrite(<файловая переменная>);
Файл инициируется для записи. Процедурой Rewrite нельзя инициировать запись информации в ранее существовавшей дисковый файл: при выполнении этой процедуры старый файл уничтожается. При открытии указатель текущей позиции в файле устанавливается в его начало.
Close(<файловая переменная>);
Процедура – закрывает ранее открытый файл, однако связь файловой переменной с именем файла, установленная ранее процедурой Assign, сохраняется.
Eof(<файловая переменная>): Boolean;
Функция – логическая функция, тестирующая конец файла. Возвращает True, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении – что файл исчерпан.
Ioresult: Word;
Функция возвращает условный признак последней операции ввода-вывода. Если операция завершилась успешно, функция возвращает ноль, иначе – код ошибочной операции. Функция Ioresult становится доступной только при отключенном автоконтроле ошибок ввода-вывода. Директива компилятора {$I-} отключает, а директива {$I+} включает автоконтроль.
Пример.Вычислить сумму элементов в файле myfile.dat
Var
f: File of integer;
X:integer;
Summa:longint;
Begin
{$I-} {отключить контроль ошибок ввода-вывода}
Assign(f, ‘c:\myfile.dat’);
Reset(f);
{$I+} {включить контроль ошибок ввода-вывода}
If Ioresult <>0 Then
begin
Writeln(‘Ошибка открытия файла’);
Halt(1) {останавливает выполнение программы и передает управление операционной системе}