Слайд 2
© С.В.Кухта, 2009
Символьные и строковые константы
Стандартные функции и
процедуры обработки строк
Множества
Примеры решения задач
Содержание
Слайд 3
© С.В.Кухта, 2009
1. Символы и строки
Слайд 4
© С.В.Кухта, 2009
В Теме 3 рассматривались произвольные массивы.
Перейдем теперь к изучению массивов специального вида - линейных
массивов, состоящих только из символов, - строк.
Слайд 5
© С.В.Кухта, 2009
Чем плох массив символов?
var B: array[1..N]
of char;
Это массив символов:
каждый символ – отдельный объект;
массив имеет
длину N, которая задана при объявлении
Что нужно:
обрабатывать последовательность символов как единое целое
строка должна иметь переменную длину
Слайд 6
© С.В.Кухта, 2009
В разделе var строки описываются следующим
образом:
Описание символьных строк
Максимальная длина строки - 255 символов.
Нумеруются ее компоненты начиная с 0, но этот нулевой байт хранит длину строки.
Если <длина> не указана, то считается, что в строке 255 символов.
Поэтому для экономии памяти следует по возможности точно указывать длину используемых строк.
var <имя_строки>: string[<длина>];
Слайд 7
© С.В.Кухта, 2009
длина строки
рабочая часть
s[1]
s[2]
s[3]
s[4]
var s: string;
var s:
string[20];
Длина строки:
n := length ( s );
var n: integer;
Описание
символьных строк
Слайд 8
© С.В.Кухта, 2009
Необходимо отметить, что один символ и
строка длиной в один символ
Описание символьных строк
совершенно не
эквивалентны друг другу.
Вне зависимости от своей реальной длины, строка относится к конструируемым структурированным типам данных, а не к базовым порядковым (см. Тему 2).
var c: char; s: string[1];
Слайд 9
© С.В.Кухта, 2009
В тексте программы на языке Паскаль
последовательность любых символов, заключенная в апострофы, воспринимается как символ
или строка.
Например:
Символ-константа и строка-константа: неименованные константы
c:='z'; {c: char}
s:='abc'; {s: string}
Слайд 10
© С.В.Кухта, 2009
Константе автоматически присваивается "минимальный" тип данных,
достаточный для ее представления:
char или string[k].
Поэтому попытка написать
Символ-константа
и строка-константа: неименованные константы
вызовет ошибку уже на этапе компиляции.
c:='zzz'; {c: char}
Слайд 11
© С.В.Кухта, 2009
Пустая строка задается двумя последовательными апострофами:
Символ-константа
и строка-константа: неименованные константы
st:=''; { пустая строка }
Если
же необходимо сделать так, чтобы среди символов строки содержался и сам апостроф, его нужно удвоить:
Если теперь вывести на экран эту строку, то получится следующее:
Don't worry about the apostrophe!
s:='Don''t worry about the apostrophe!';
Слайд 12
© С.В.Кухта, 2009
Все правила задания символов и строк
как неименованных констант остаются в силе и при задании
именованных нетипизированных констант в специальном разделе const.
Например:
Символ-константа и строка-константа: нетипизированные константы
const c3 = ''''; {это один символ - апостроф!}
s3 = 'Это строка';
Слайд 13
© С.В.Кухта, 2009
Типизированная константа, которая будет иметь тип
char или string, задается в разделе const следующим образом:
Символ-константа и строка-константа: типизированные константы
const c4: char = '''';
{это один символ - апостроф!}
s4: string[20] = 'Это строка';
Слайд 14
© С.В.Кухта, 2009
Результатом унарной операции
Действия с символами:
операции
является символ, номер которого в таблице ASCII соответствует заданному
числу.
Например,
#<положительная неименованная константа целого типа>
#100 = 'd'
#39 = '''' {апостроф}
#232 = 'ш'
#1000 = 'ш' {потому что (1000 mod 256)= 232}
Слайд 15
© С.В.Кухта, 2009
Кроме того, к символьным переменным, как
и к значениям всех порядковых типов данных, применимы операции
сравнения
<, <>, >, =,
результат которых также опирается на номера символов из таблицы ASCII.
Действия с символами: операции
Слайд 16
© С.В.Кухта, 2009
Функция
chr(k:byte):char
"превращает"; номер символа в
символ.
Действие этой функции аналогично действию операции #.
Например:
Действия с символами: стандартные функции
c:= chr(48); { c: char }
{ c = '0' }
Слайд 17
© С.В.Кухта, 2009
Обратной к функции chr() является уже
изученная нами функция ord().
Таким образом, для любого числа
k и для любого символа с
Действия с символами: стандартные функции
ord(chr(k)) = k ;
chr(ord(c)) = c;
Слайд 18
© С.В.Кухта, 2009
Cтандартные процедуры и функции
pred(),
succ(), inc() и dec(),
определенные для значений любого
порядкового типа, применимы также и к символам (значениям порядкового типа данных char).
Например:
Действия с символами: стандартные функции
pred('[') = 'Z'
succ('z') = '{'
inc('a') = 'b'
inc('c', 2) = 'e'
dec('z') = 'y'
dec(#0, 4) = '№' {#252}
Слайд 19
© С.В.Кухта, 2009
Стандартная функция
upcase(c: char):char
превращает строчную
букву в прописную.
Символы, не являющиеся строчными латинскими буквами,
остаются без изменения (к сожалению, в их число попадают и все русские буквы).
Действия с символами: стандартные функции
Слайд 20
© С.В.Кухта, 2009
Строки могут быть элементами списка ввода–вывода,
при этом записывается имя строки без индекса.
Для ввода
нескольких строковых данных следует пользоваться оператором Readln, так как оператор Read в этих случаях может вести себя непредсказуемо.
При вводе строковых переменных количество вводимых символов может быть меньше, чем длина строки. В этом случае вводимые символы размещаются с начала строки, а оставшиеся байты заполняются пробелами.
Если количество вводимых символов превышает длину строки, лишние символы отбрасываются.
Ввод-вывод строковых переменных
Слайд 21
© С.В.Кухта, 2009
Особенностью строковых переменных является то, что
к ним можно обращаться
как к скалярным переменным,
так
и к массивам.
Во втором случае применяется конструкция "переменная с индексом", что обеспечивает доступ к отдельным символам строки. При этом нижняя граница индекса равна 1.
Отдельный символ строки совместим с типом char.
Например,
Обращение к строковым переменным
S:= St[20]; { обращение к 20 эл-ту строки St }
Po:='Компьютер'; { инициализация строки }
Fillchar (a, sizeof(a), '0');
{ заполнение строки a символьными ’0’ }
Слайд 22
© С.В.Кухта, 2009
Например, если в программе определены
Var S:
string; C: char;
и задано
S:='Москва',
то
S[1]='М',
S[2]='о' и т. д.
Обращение к строковым переменным
Слайд 23
© С.В.Кухта, 2009
Элементы массива, составляющие строку можно переставлять
местами и получать новые слова.
Пример 1. Вывод исходного
слова справа налево: "авксоМ"
Обращение к строковым переменным
for i:=1 to N div 2 do begin
C:=S[i]; S[i]:=S[N-i+1]; S[N-i+1]:=C end;
Writeln(S);
Пример 2. Поиск и замена заданного символа в строке
for i:=1 to N do
if S[i]='_' then writeln('найден символ пробел');
for i:=1 to N do
if S[i]='/' then S[i]:='\';
{ замена символа "/" на "\" }
Слайд 24
© С.В.Кухта, 2009
2. Операции, стандартные функции и процедуры,
выполняемые над строковыми переменными
Слайд 25
© С.В.Кухта, 2009
Для строк определены операции:
присваивания,
слияния (конкатенации,
объединения),
сравнения.
Операции, выполняемые над строками
Слайд 26
© С.В.Кухта, 2009
Результатом выполнения операции конкатенации "+", является
строка, в которой исходные строки-операнды соединены в порядке их
следования в выражении.
Например,
Операция конкатенации
X:='Пример'; Y:='сложения'; Z:='строк';
Writeln(X + Y + Z);
Writeln(Y + ' ' + Z + ' ' + X);
На экран будут выведены строки:
Примерсложениястрок
сложения строк Пример
'Кро'+' 'код'+ 'ил'
позволит получить новую строку
'Крокодил'
Слайд 27
© С.В.Кухта, 2009
Тип String допускает и пустую строку
– строку, не содержащую символов:
EmptyStr := '';
{подряд идущие кавычки}.
Она играет роль нуля (нейтрального элемента) операции конкатенации:
EmptyStr + X = X + EmptyStr = X.
Операция конкатенации
Слайд 28
© С.В.Кухта, 2009
Строки - это единственный структурированный тип
данных, для элементов которого определен порядок и, следовательно, возможны
операции сравнения.
Сравнение строк происходит посимвольно, начиная с первого символа.
Строки равны, если имеют одинаковую длину и посимвольно эквивалентны.
Над строками определены также отношения (операции логического типа):
=, <>, <, >, <=, >=.
Операция сравнения
Слайд 29
© С.В.Кухта, 2009
Таким образом, каждый из строковых типов
упорядочен лексикографически. Это означает, что
порядок на строках согласован с
порядком, заданным на символьном типе (Char);
сравнение двух строк осуществляется посимвольно, начиная с первых символов;
если строка A есть начало строки B, то A < В;
пустая строка – наименьший элемент типа.
Итак,
Операция сравнения
'abc' < 'xyz'
'Иванов' < 'Иванова'
'1200' < '45'
'Татьяна' < 'татьяна'
Слайд 30
© С.В.Кухта, 2009
Формат:
Функция Length
Length(X :string ): byte;
Возвращает
длину строки - аргумента X. Причем, длина пустой строки
Length(EmptyStr) = 0.
Тип результата – Byte.
Примеры:
Исходные данные: S := ‘крокодил‘;
Оператор: j := length(S);
Результат: j = 8
Исходные данные: T := ‘Компьютерный класс‘;
Оператор: j := length(T);
Результат: j = 18
Слайд 31
© С.В.Кухта, 2009
Задача: ввести строку с клавиатуры и
заменить все буквы «а» на буквы «б».
program qq;
var s:
string;
i: integer;
begin
writeln('Введите строку');
readln(s);
for i:=1 to Length(s) do
if s[i] = 'а' then s[i] := 'б';
writeln(s);
end.
readln(s);
writeln(s);
Length(s)
ввод строки
длина строки
вывод строки
Функция Length
Слайд 32
© С.В.Кухта, 2009
Формат:
Функция Copy
Copy(X :string; Index, Count :byte):
string;
Копирует (выделяет) подстроку строки X, начиная с позиции Index
и содержащую следующие Count символов.
Тип результата – String.
Если Index больше длины строки, то результатом будет пустая строка.
Если же Count больше, чем длина оставшейся части строки, то результатом будет только ее "хвост":
Слайд 33
© С.В.Кухта, 2009
s := '123456789';
s1 := Copy (
s, 3, 6 );
s2 := Copy ( s1,
2, 3 );
'345678'
'456'
с 3-его символа
6 штук
Функция Copy
Исходные данные: S := ‘крокодил‘;
Оператор: b:= cору(S, 2, 3);
Результат: b = 'рок'.
Исходные данные: T := ‘Компьютерный класс‘;
Оператор: c:= cору(T, 14, 53);
Результат: c = 'класс'.
copy('abc3de Xyz', 2, 4) = 'bc3d'
copy('abc3de Xyz', 12, 4) = ''
copy('abc3de Xyz', 8, 14) = 'Xyz'
Слайд 34
© С.В.Кухта, 2009
Формат:
Функция Concat
Concat(X1, X2, .., Xk :string):string
Объединение (конкатенация) строк или символов Х1, X2, .., Xk
в указанном порядке. Другая форма записи: X1+X2+ .. +Xk.
Тип результата – String.
Если длина итоговой строки больше 255-ти символов, то произойдет отсечение "хвоста".
Кроме того, даже если результат конкатенации не был усечен, но программа пытается сохранить его в переменную заведомо меньшей длины, то усечение все равно состоится
Слайд 35
© С.В.Кухта, 2009
Функция Concat
Примеры:
Исходные данные: a := 'код‘;
b := 'ил‘;
Оператор: S := concat('кро', a, b).
Результат: S
= 'крокодил'.
concat('abc', '3de', ' ', 'X', 'yz') = 'abc3de Xyz'
Слайд 36
© С.В.Кухта, 2009
Формат:
Функция Pos
Pos(Y, X :string ): byte;
Отыскивает
первое вхождение строки Y в строке X (считая слева
направо) и возвращает номер начальной позиции вхождения.
Если X не содержит Y, функция вернет 0 (Pos(Y, X) = 0).
Тип результата – Byte.
Примеры:
Исходные данные: S := ‘крокодил‘;
Оператор: i := pos('око‘, S);
Результат: i = 3.
Оператор: i := pos('я', ‘крокодил');
Результат: i = 0.
Слайд 37
© С.В.Кухта, 2009
Поиск в строке
Поиск в строке:
s :=
'Здесь был Вася.';
n := Pos ( 'е', s );
if
n > 0 then
writeln('Буква е – это s[', n, ']')
else writeln('Не нашли');
n := Pos ( 'Вася', s );
s1 := Copy ( s, n, 4 );
s[3]
3
n = 11
Особенности:
функция возвращает номер символа, с которого начинается образец в строке
если слова нет, возвращается 0
поиск с начала (находится первое слово)
var n: integer;
Слайд 38
© С.В.Кухта, 2009
Формат:
Процедура Delete
Delete(X :string; Index, Count :byte);
Удаляет из строки X подстроку, начиная с позиции, заданной
числом Index, длиной, заданной числом Count.
Тип результата – String.
Если число Index больше размера строки, то подстрока не удаляется.
Если число Count больше имевшегося количества, то удаляются символы до конца строки.
Тип результата – String.
Слайд 39
© С.В.Кухта, 2009
s := '123456789';
Delete ( s, 3,
6 );
с 3-его символа
6 штук
строка
меняется!
'123456789'
'129'
Процедура Delete
Исходные данные:
S := 'крокодил‘;
Оператор: delete(S, 4, 3);
Результат: S = 'кроил'.
Оператор: delete(S, 1, 1);
Результат: S = 'роил'.
Исходные данные: s = 'abc3de Xyz'
Оператор: delete(S, 8, 13);
Результат: S = 'abc3de '.
Слайд 40
© С.В.Кухта, 2009
Формат:
Процедура Insert
Insert(Y, X :string; Index :byte);
Вставляет
строку Y в строку X, начиная с позиции, заданной
числом Index.
Тип результата – String.
Если Index выходит за конец строки, то подстрока Y припишется в конец строки X.
Если результат длиннее, чем допускается для строки X, произойдет его усечение справа.
Слайд 41
© С.В.Кухта, 2009
s := '123456789';
Insert ( 'ABC', s,
3 );
Insert ( 'Q', s, 5 );
куда вставляем
что
вставляем
начиная с 3-его символа
'12ABC3456789'
'12ABQC3456789'
Процедура Insert
Исходные данные: S := 'крокодил‘;
Оператор: d := сору(S, 3, 3);
Результат: d = 'око'.
Оператор: insert('H', d, 3);
Результат: d = 'окНо'.
Слайд 42
© С.В.Кухта, 2009
Примеры
s := 'Вася Петя Митя';
n :=
Pos ( 'Петя', s );
Delete ( s, n, 4
);
Insert ( 'Лена', s, n );
'Вася Лена Митя'
s := 'Вася Петя Митя';
n := length ( s );
s1 := Copy ( s, 1, 4 );
s2 := Copy ( s, 11, 4 );
s3 := Copy ( s, 6, 4 );
s := s3 + s1 + s2;
n := length ( s );
'Вася Митя'
14
'Вася'
'Митя'
'Петя'
'ПетяВасяМитя'
12
6
Слайд 43
© С.В.Кухта, 2009
Формат:
Процедура Val
VAL(St :string; Ibr :; Cod
:byte );
Преобразует строку символов St в величину целочисленного или
вещественного типа и помещает результат в Ibr.
Ibr является внутренним представлением числа, записанного в символьном формате.
Значение St не должно содержать незначащих пробелов в начале и в конце.
Cod – целочисленная переменная, указывающая номер позиции первого неправильного символа, или равная 0 в случае успешного преобразования.
Слайд 44
© С.В.Кухта, 2009
Преобразование из строки в число:
s :=
'123';
Val ( s, N, r ); { N =
123 }
{ r = 0, если ошибки не было
r – номер ошибочного символа}
s := '123.456';
Val ( s, X, r ); { X = 123.456 }
var N: integer;
X: real;
s: string;
Процедура Val
Исходные данные: St := ‘1500’;
Оператор: Val(St, Ibr, Cod);
Результат: Ibr = 1500 Cod = 0
Исходные данные: St := ‘4.8A+03’;
Оператор: Val(St, Ibr, Cod);
Результат: Ibr = ??? Cod = 5
Слайд 45
© С.В.Кухта, 2009
Формат:
Процедура Str
STR(Ibr [:M [:N] ], St:string
);
Преобразует числовое значение величины Ibr в строковое и помещает
результат в строку St.
M задает общее количество символов, получаемых в строке,
N - для вещественных чисел (типа real) задает количество цифр в дробной части.
Тип результата – String.
Если в формате указано недостаточное для вывода количество разрядов, поле вывода расширяется автоматически до нужной длины.
Если число короче указанных величин, то спереди и/или сзади оно будет дополнено пробелами.
Слайд 46
© С.В.Кухта, 2009
Преобразование из числа в строку:
N :=
123;
Str ( N, s ); { '123'
}
X := 123.456;
Str ( X, s ); { '1.234560E+002' }
Str ( X:10:4, s ); { ' 123.456 ' }
var N: integer;
X: real;
s: string;
Процедура Str
Исходные данные: Ibr := 1500;
Оператор: str(Ibr:6, S);
Результат: S = ‘__1500’.
Исходные данные: Ibr := 4.8E+03;
Оператор: str(Ibr:10, S);
Результат: S = ‘______4800’.
Слайд 47
© С.В.Кухта, 2009
3. Примеры обработки символьных данных
Слайд 48
© С.В.Кухта, 2009
Пример 1. Проверить, является ли заданный
символ S строчной гласной буквой русского алфавита.
Решение. pos(S, 'аэоуыяеёюи')
> 0
Пример 2. Выделить часть строки после первого пробела.
Решение.
copy(s, pos(' ', s)+1, Length(s)-pos(' ', s))
Пример 3. Удалить последний символ строки S.
Решение. delete(S, Length(S), 1)
Пример 4. Выделить из строки S подстроку между i-й и j-й позициями, включая эти позиции.
Решение. copy(s, i, j-i+1)
Слайд 49
© С.В.Кухта, 2009
Пример 5. Подсчитать, сколько раз в
заданной строке встречается указанная буква.
Решение 1. Обозначим заданную
строку - s, а искомую букву - a. Тогда для решения задачи будем просматривать заданную строку посимвольно и каждый символ сравнивать с заданной буквой.
Решение 2. Ищем положение указанной буквы в строке до тех пор, пока ее удастся найти. Затем отбрасываем ту часть строки, где была найдена указанная буква, и повторяем поиск.
k:=0; { количество указанных букв в строке }
for i:=1 to Length(s) do
if copy(s, i, 1)=a then k:=k+1;
k:=0; j:=pos(a, s); { позиция 1-го вхождения а в строку s }
while j<>0 do begin
k:=k+1;
s:=copy(s, j+1, Length(s)-j); j:=pos(a, s)
end;
Слайд 50
© С.В.Кухта, 2009
Пример 6. Назовем словом любую последовательность
букв и цифр. Строка состоит из слов, разделенных одним
или несколькими пробелами. Удалить лишние пробелы, оставив между словами по одному пробелу.
Решение. Лишними пробелами называются второй, третий и т.д., следующие за первым пробелом. Следовательно, чтобы найти лишний пробел, нужно искать два пробела, стоящие рядом, и удалять второй пробел в каждой найденной паре.
j:=pos(' ', s);
while j<>0 do begin
delete(s, j, 1);
j:=pos(' ', s)
end;
Слайд 51
© С.В.Кухта, 2009
Пример решения задачи
Задача: Ввести имя, отчество
и фамилию. Преобразовать их к формату «фамилия-инициалы».
Пример:
Введите имя, фамилию и отчество:
Василий Алибабаевич Хрюндиков
Результат:
Хрюндиков В.А.
Алгоритм:
найти первый пробел и выделить имя
удалить имя с пробелом из основной строки
найти первый пробел и выделить отчество
удалить отчество с пробелом из основной строки
«сцепить» фамилию, первые буквы имени и фамилии, точки, пробелы…
Слайд 52
© С.В.Кухта, 2009
Программа
program qq;
var s, name, otch: string;
n: integer;
begin
writeln('Введите имя, отчество и фамилию');
readln(s);
n := Pos(' ', s);
name := Copy(s, 1, n-1); { вырезать имя }
Delete(s, 1, n);
n := Pos(' ', s);
otch := Copy(s, 1, n-1); { вырезать отчество }
Delete(s, 1, n); { осталась фамилия }
s := s + ' ' + name[1] + '.' + otch[1] + '.';
writeln(s);
end.
Слайд 53
© С.В.Кухта, 2009
Задания
Ввести имя файла (возможно, без расширения)
и изменить его расширение на «.exe».
Пример:
Введите
имя файла: Введите имя файла:
qqq qqq.com
Результат: Результат:
qqq.exe qqq.exe
Ввести полный путь к файлу и «разобрать» его, выводя каждую вложенную папку с новой строки
Пример:
Введите путь к файлу:
C:\Мои документы\09ИТ-3\Вася\qq.exe
Результат:
C:
Мои документы
09ИТ-3
Вася
qq.exe
Слайд 54
© С.В.Кухта, 2009
Посимвольный ввод
Задача: с клавиатуры вводится число
N, обозначающее количество футболистов команды «Шайба», а затем –
N строк, в каждой из которых – информация об одном футболисте таком формате:
<Фамилия> <Имя> <год рождения> <голы>
Все данные разделяются одним пробелом. Нужно подсчитать, сколько футболистов, родившихся в период с 1988 по1990 год, не забили мячей вообще.
Алгоритм:
for i:=1 to N do begin
{ пропускаем фамилию и имя }
{ читаем год рождения Year и число голов Gol }
if (1988 <= Year) and (Year <=1990) and
(Gol = 0) then { увеличиваем счетчик }
end;
Слайд 55
© С.В.Кухта, 2009
Посимвольный ввод
Пропуск фамилии:
repeat
read(c);
until c =
' '; { пока не встретим пробел }
var c:
char;
Пропуск имени:
repeat read(c); until c = ' ';
Ввод года рождения:
read(Year); { из той же введенной строки }
var Year: integer;
Ввод числа голов и переход к следующей строке:
readln(Gol); { читать все до конца строки }
var Gol: integer;
Слайд 56
© С.В.Кухта, 2009
Программа
program qq;
var c: char;
i,
N, count, Year, Gol: integer;
begin
writeln('Количество футболистов');
readln(N);
count
:= 0;
for i:=1 to N do begin
repeat read(c); until c = ' ';
repeat read(c); until c = ' ';
read(Year);
readln(Gol);
if (1988 <= Year) and (year <= 1990) and
(Gol = 0) then count := count + 1;
end;
writeln(count);
end.
repeat read(c); until c = ' ';
repeat read(c); until c = ' ';
read(Year);
readln(Gol);
Слайд 57
© С.В.Кухта, 2009
Посимвольный ввод
Если фамилия нужна:
fam := '';
{ пустая строка }
repeat
read(c);
{ прочитать символ }
fam := fam + c; { прицепить к фамилии }
until c = ' ';
Вместо read(Year):
s := ''; { пустая строка }
repeat
read(c); { прочитать символ }
s := s + c; { прицепить к фамилии }
until c = ' ';
Val(s, Year, r); { строку – в число }
var fam: string;
var s: string;
Слайд 58
© С.В.Кухта, 2009
Посимвольный ввод
Если нужно хранить все фамилии:
const
MAX = 100;
var fam: array[1..MAX] of string;
...
fam[i] := '';
{ пустая строка }
repeat
read(c); { прочитать символ }
fam[i] := fam[i] + c;
until c = ' ';
массив символьных строк
Слайд 60
© С.В.Кухта, 2009
Множество – это структурированный тип данных,
представляющий собой набор взаимосвязанных по какому-либо признаку или группе
признаков объектов, которые можно рассматривать как единое целое.
Каждый объект в множестве называется элементом множества.
Все элементы множества должны принадлежать одному из скалярных типов, кроме вещественного. Этот тип называется базовым типом множества.
Базовый тип задается диапазоном или перечислением.
Слайд 61
© С.В.Кухта, 2009
Область значений типа множество – набор
всевозможных подмножеств, составленных из элементов базового типа.
В выражениях
на Паскале значения элементов множества указываются в квадратных скобках:
[1, 2, 3, 4], [‘a’, ‘b’, ‘c’], [‘a’..’z’].
Если множество не имеет элементов, оно называется пустым и обозначается как [ ].
Слайд 62
© С.В.Кухта, 2009
Количество элементов называется его мощностью.
Количество
элементов множества не должно превышать 256, соответственно номера значений
базового типа должны находиться в диапазоне 0..255.
Важное отличие множества от остальных структурированных типов состоит в том, что его элементы не являются упорядоченными.
Слайд 63
© С.В.Кухта, 2009
Формат записи множественного типа и переменной,
относящейся к нему:
Описание множества
Type = set
of
<тип_элементов_множества>;
Var <идентификатор, …> : <имя типа>;
В разделе var множества описываются следующим образом (без предварительного описания типа):
Var <имя_множества>: set of
<тип_элементов_множества>;
Элементы могут принадлежать к любому порядковому типу, размер которого не превышает 1 байт (256 элементов).
Слайд 64
© С.В.Кухта, 2009
Описание множества: примеры
type
Simply
= set of ’a’..’h’;
Number = set of
1..31;
Var Pr : Simply;
N : Number;
Letter : set of char;
Var s2: set of 'a'..'z','A'..'Z';
{множество из 52-х элементов}
s3: set of 0..10; {множество из 11-ти элементов}
s4: set of boolean; {множество из 2-х элементов}
Pr может принимать значения символов латинского алфавита от ‘a’ до ‘h’;
N – любое значение в диапазоне 1...31;
Letter – любой символ;
Слайд 65
© С.В.Кухта, 2009
Множество можно задать неименованной константой прямо
в тексте программы. Для этого необходимо заключить список элементов
создаваемого множества в квадратные скобки:
Множество-константа: неименованная константа
[<список_элементов>]
Список элементов может быть задан перечислением элементов нового множества через запятую, интервалом или объединением этих двух способов.
Элементы и границы интервалов могут быть переменными, константами и выражениями. Если левая граница интервала окажется больше правой, результатом будет пустое множество.
Слайд 66
© С.В.Кухта, 2009
Примеры конструирования и использования различных множеств:
Множество-константа: неименованная константа
if c in ['a','e','i','o','u'] then
writeln('Гласная
буква');
if set1 < [k*2+1 .. n, 13] then
set1:=[];
Слайд 67
© С.В.Кухта, 2009
Множество - это структурированный тип данных,
поэтому его невозможно задать нетипизированной константой!
Множество-константа: нетипизированная константа
Слайд 68
© С.В.Кухта, 2009
Задать множество как типизированную константу можно
в разделе const:
: set of
=[];
Множество-константа: типизированная константа
Например,
type cipher = set of '0'..'9';
const odds: cipher = ['1','3','5','7','9'];
vowels: set of 'a'..'z'=['a','o','e','u','i'];
Слайд 69
© С.В.Кухта, 2009
5. Операции с множествами
Слайд 70
© С.В.Кухта, 2009
Использование в программе данных типа set
дает ряд преимуществ:
значительно упрощаются сложные операторы if,
увеличивается степень
наглядности программы и понимания решения задачи,
экономится память, время компиляции и выполнения.
Имеются и отрицательные моменты.
Основной из них – отсутствие в языке Паскаль средств ввода-вывода элементов множества, поэтому программист сам должен писать соответствующие процедуры.
Слайд 71
© С.В.Кухта, 2009
При работе с множествами допускается использование
операций:
отношения =, , >=,
множеств
пересечения множеств
разности множеств.
Результатом выражений с применением первых двух операций является значение True или False.
Слайд 72
© С.В.Кухта, 2009
Два множества А и В считаются
равными, если они состоят из одних и тех же
элементов.
Порядок следования элементов в сравниваемых множествах значения не имеет.
Например,
Операция «Равно» (=)
Слайд 73
© С.В.Кухта, 2009
Два множества А и В считаются
не равными, если они отличаются по мощности или по
значению хотя бы одного элемента.
Например,
Операция «Неравно» (<>)
Слайд 74
© С.В.Кухта, 2009
Операция «больше или равно» используется для
определения принадлежности множеств.
Результат операции А >= В равен
True, если все элементы множества В содержатся в множестве А. В противном случае результат равен False.
(A⊇B)
Например,
Операция «Больше или равно» (>=)
Слайд 75
© С.В.Кухта, 2009
Эта операция используется аналогично предыдущей операции,
но результат выражения А
множества A содержатся в множестве B. В противном случае результат равен False.
(A⊆B)
Например,
Операция «Меньше или равно» (<=)
Слайд 76
© С.В.Кухта, 2009
Эта операция используется для проверки принадлежности
какого-либо значения указанному множеству. Обычно применяется в условных операторах.
(a∈B)
Например,
Операция
IN
При использовании операции in проверяемое на принадлежность значение и множество в квадратных скобках не обязательно предварительно описывать в разделе описаний.
Слайд 77
© С.В.Кухта, 2009
Операция in позволяет эффективно и наглядно
производить сложные проверки условий, заменяя иногда десятки других операций.
Например, выражение
Операция IN
можно заменить более коротким выражением
if (a=1) or (a=2) or (a=4)
or (a=5) or (a=6) then …
if a in [1..6] then …
Слайд 78
© С.В.Кухта, 2009
Часто операцию in пытаются записать с
отрицанием:
X NOT in M
(x∉M)
Такая запись является ошибочной, так
как две операции следует подряд.
Правильная конструкция имеет вид
Операция отрицания IN
NOT (X in M)
Слайд 79
© С.В.Кухта, 2009
Объединением двух множеств является третье множество,
содержащее элементы обоих множеств (A∪B).
Графическая интерпретация:
Например,
Операция «Объединение» (+)
Слайд 80
© С.В.Кухта, 2009
Пересечением двух множеств является третье множество,
которое содержит элементы, входящие одновременно в оба множества(A∩B).
Графическая
интерпретация:
Например,
Операция «Пересечение» (*)
Слайд 81
© С.В.Кухта, 2009
Разностью двух множеств является третье множество,
которое содержит элементы первого множества, не входящие во второе
множество (A \ B).
Графическая интерпретация:
Например,
Операция «Разность» (–)
Слайд 82
© С.В.Кухта, 2009
Не существует никакой процедуры, позволяющей распечатать
содержимое множества. Это приходится делать следующим образом:
{s: set
of type1; k: type1}
for k:= min_type1 to max_type1 do
if k in s then
write(k);
Слайд 83
© С.В.Кухта, 2009
6. Примеры использования символов, строк и
множеств
Слайд 84
© С.В.Кухта, 2009
Задано множество целых положительных чисел от
1 до n. Создать из элементов этого множества такие
подмножества, элементы которых удовлетворяют следующим условиям:
Элементы подмножества не большие 10;
Элементы подмножества кратны 8;
Элементы подмножества не кратны 3 и 6.
Пример 1
Слайд 85
© С.В.Кухта, 2009
Program mnoj;
Const n=100;
Var mn1, mn2, mn3:
set of 1..n;
k: integer;
Begin
{задание начальных значений
подмножеств (пустые)}
mn1:=[]; mn2:=[]; mn3:=[];
for k:=1 to n do begin {создание подмножеств}
if k<=10 then mn1:=mn1 + [k];
if k mod 8 =0 then mn2:=mn2 + [k];
if (k mod 3<>0) and (k mod 6<>0) then mn3:=mn3 + [k];
end;
Пример 1
Слайд 86
© С.В.Кухта, 2009
{печать полученных множеств}
writeln(’подмножество чисел не больших
10’);
for k:=1 to n do
if k in mn1
then write(k:4);
writeln(’подмножество чисел кратных 8’);
for k:=1 to n do
if k in mn2 then write(k:4);
writeln(’подмножество чисел не кратных 3 и 6’);
for k:=1 to n do
if k in mn3 then write(k:4);
end.
Пример 1
Слайд 87
© С.В.Кухта, 2009
Дан текст. Вывести на экран те
буквы из текста, которые встречаются в данном тексте только
один раз.
Пример 2
program mnogestvo;
Var mn1, mn2: set of char;
i: integer; Stroka: string;
Begin
writeln('Введите строку '); readln(Stroka);
mn1:=[]; mn2:=[]; {Пустые множества}
for i:=1 to Length(Stroka) do
if Stroka[i] in mn1 then mn2:=mn2+[Stroka[i]]
else mn1:=mn1 + [Stroka[i]];
for i:=1 to Length(Stroka) do
if (not(Stroka[i] in mn2)) then writeln(Stroka[i]);
end.
mn2 – содержит парные буквы
mn1 – содержит все встречающиеся буквы в строке
Вывод тех букв, которых нет в множестве mn2
Слайд 88
© С.В.Кухта, 2009
Оставить в строке только первое вхождение
каждого символа, взаимный порядок оставленных символов сохранить.
Пример 3
program
z3;
var s: set of char;
inp, res: string; i: byte;
begin
s:=[]; res:= '';
for i:=1 to length(inp) do
if not(inp[i] in s) then begin
res:= res+inp[i]; s:= s+[inp[i]];
end;
end.
s – содержит все встречающиеся буквы в строке;
inp – исходная строка;
res – результирующая строка
Слайд 89
© С.В.Кухта, 2009
Оставить в строке только последнее вхождение
каждого символа, взаимный порядок оставленных символов сохранить.
Пример 4
program
z3;
var inp, res: string;
i: byte;
begin
res:= '';
for i:=1 to length(inp) do begin k:= pos(inp[i], res);
if k<>0 then delete(res, k, 1); res:= res+inp[i];
end;
end.
inp – исходная строка;
res – результирующая строка
Слайд 90
© С.В.Кухта, 2009
Задано предложение, состоящее из слов, разделенных
одним или несколькими пробелами. Определить самое длинное слово предложения.
Решение.
Чтобы выделить окончание слова, нужно анализировать два символа:
первый символ должен быть отличен от пробела,
а второй должен быть пробелом.
Для одинаковой обработки всех символов предложения добавим к концу предложения дополнительный символ - пробел.
Как только обнаружится конец слова, вычислим его длину и проверим на максимум:
Пример 5
Слайд 91
© С.В.Кухта, 2009
Пример 5
smax:=''; { слово максимальной длины
}
readln(s); { исходное предложение }
s:=s+' '; { исходное предложение
с доп. пробелом }
ss:='' { текущее слово предложения }
for i:=1 to length(s)-1 do
{ просмотр предложения по два символа }
if s[i]<>' ') and s[i+1]=' ') then begin
{ если текущий символ не пробел, а следующий - пробел }
ss:=ss+s[i]; { дописали последний символ }
if length(smax) то запоминаем его }
ss:='' { готовим место для следующего слова }
end
else if s[i]<>' ' then ss:=ss+s[i];
{ если текущий символ не пробел, то запоминаем его в слове }.