Это тоже полезное действие, которое часто применяется в системах хранения и поиска данных. Дело в том, что при сравнении строк обязательно учитывается регистр, поэтому такие способы записи одного слова, как компьютер, компьютер и компьютер будут восприняты как три разных слова, а в отсортированном списке они будут располагаться даже не рядом друг с другом. Учитывая данное обстоятельство, обычно при вводе информации выполняют преобразование слова к буквам какого-то одного регистра, чаще к заглавным буквам.
Начнем с простого примера. Преобразуем все строчные английские буквы введенной строки в заглавные. Для этого достаточно знания одной функции upcase, которая преобразует к верхнему регистру один символ (листинг 9.7).
I Листинг 9.7. Преобразование строчных латинских букв в заглавные
var s: string/procedure upstring(var s:string);) процедура преобразования строки } var i: integer; begin
for i:=l to length(s) do
s[i]:=upcase(s[i]); { преобразование одного символа } end; begin { начало основной программы }
write('Введите исходную строку:');readln{з);
upstring(s); writeln(s); readln; end.
Усложним задачу. Пусть требуется преобразовать в строке строчные буквы русского алфавита в заглавные. Функция upcase с символами русского алфавита не работает. Придется писать свою функцию, работающую с русскими буквами.
Будем использовать две вспомогательные строки: строку из всех заглавных букв русского алфавита и строку всех строчных букв. Заметим, что здесь обязательным является применение типизированных констант (или переменных), т. к. обычная строковая константа не может интерпретироваться как массив символов (листинг 9.8).
Г Листинг 9.8. Преобразование русских букв в заглавные
var s:string;
function upstringrus(s:string):string; const small:з^1пд='абвгдежзиклмнопрстуфхцчишгьыьэюя'; big:s tring='АБВГДЕЖЗИКЛ1даОПРСТУФХЦЧШЩЬЫЬЭЮЯ'; var i,n:integer; begin
for i:=l to lengthfs) do begin
n:=pos{s[i],small);{ находим номер символа в строке строчных букв) if n>0 then s[i]:=big[n];{ заглавная буква с таким же номером }
end;
upstringrus:=s; end; begin
write('Введите строку');readln(s);
writeln(upstringrus(s)); readln; end.
Чтобы окончательно закрыть эту тему, приведем заключительный пример. Процедура getupstr преобразует русские и английские буквы в заглавные непосредственно при вводе. Буква вводится в любом регистре, а на экране — всегда заглавная. Такой способ ввода используется в различных программах, теперь есть возможность узнать, как это делается (листинг 9.9).
^Листинг 9.9. Ввод строки с приведением всех букв к верхнему регистру
uses crt;
var s:string;
procedure getupstr(var st: string);
var с:char;
begin
st:='';{ сформировали пустую строй^ — это действие нельзя забывать } repeat
c:=readkey;{ слепой ввод без отображения на экране — модуль crt } case с of
{коды заглавных и прописных русских букв от А до П различаются на 32, } 'а1.. 'п1: c:=chr(ord(c)-32);
'рт.. 'я1: c:=chr(ord(c)-80); { а коды от Р до Я - на 80 } 'а1.. -z': c:=upcase(c);
end; |
if c<>#13 then { не клавиша <Enter> } begin
st:=st+c; write(с);{ добавляем символ к строке и выводим } end;
until c=#13;{ ввод завершен нажатием клавиши <Enter> } writeln; end; "begin
writeln('Введите строку текста и нажмите <Enter>'); getupstr(s); writeln('Значение s:1); writeln(s); readln
Множества
Множества имеют большое значение в математике, поэтому не удивительно, что в языке Turbo Pascal имеется такой тип данных.
Понятие множества
Множество — это набор элементов одинакового типа, которые рассматриваются как единое целое. Элементы множества не пронумерованы, следовательно, нельзя обратиться к отдельному элементу множества по его индексу. Поэтому множества используются в тех задачах, где порядок следования элементов данных не имеет значения (например, множество гласных или согласных букв, множество ходов шахматной фигуры из определенного положения и т. д.).
Тип элементов множества называется базовым типом множества. Область значений типа множества — набор всевозможных подмножеств, составленных из элементов базового типа.
В языке Turbo Pascal имеются ограничения на базовый тип. Это может быть только порядковый тип, количество значений которого не превышает 256. Из простых типов к таким относятся char, byte, boolean. Разрешается использовать перечисляемый тип и диапазон (если он включает не больше 256 элементов).
Это существенные ограничения, которые не позволяют использовать множества в серьезных задачах обработки данных. Все же для ряда задач применение множеств может обеспечить серьезные преимущества по сравнению с использованием других структур данных — массивов или строк.
При задании значений элементов множества применяются квадратные скобки.
Например: [1,2,3,4], ['а','Ь','с1Ь ['а'.. 'г'}
Если множество не имеет элементов, оно называется пустым и обозначается []. Пустое множество включено в любое другое.
Для объявления множественного типа используется словосочетание set of (множество из...). Формат объявления множественных типов следующий:
Type
ИмяТипа = set of ТипЭлементовМножества; var
ИмяПеременной,...: ИмяТипа;
Можно описать переменные множественного типа и без предварительного объявления типа:
var ИмяПеременной,...: set of Тип;
Можно объявить константы множественного типа:
const ИмяКонстанты=[ЗначениеМножества];
а также типизированные константы:
const ИмяКонстанты:ТипМножест'ва= [ЗначениеМножества];
Например:
const number - [1,4,7,9]; type simply = set of 'a'.-'h1;
var pr: simply;
letter: set of char; {без предварительного описания в разделе типов}
В данном примере в множество рг могут входить значения символов латинского алфавита от 'а' до 'h1; в множество letter — значения любых символов. Попытка присвоить другие значения вызовет ошибку выполнения.
Замечание
В памяти множества представлены особым образом. Каждому значению базового типа множества в памяти отводится 1 бит (не байт!). Следовательно, максимальный размер ячейки памяти, отводимой под множество, составляет 32 байта. Поскольку все значения порядкового типа расположены строго по порядку, 1 в соответствующем бите означает наличие данного значения в множественной переменной, а 0 — отсутствие.
Исходя из особенностей внутреннего представления множеств, можно сделать два основных вывода:
П в множестве не может быть одинаковых элементов, что согласуется и с нашими математическими знаниями;
П все операции над множествами выполняются значительно эффективней, чем над другими структурами данных.
Операции над множествами
При работе с множествами допускается использование следующих операций:
П отношения (=, <>, >=, <=);
О объединения множеств (+);
О пересечения множеств (*);
П разности множеств (—);
G проверка принадлежности элемента множеству (in).
Рассмотрим каждую из операций в отдельности.
П Операция "равно" (=). Два множества А л Л считаются равными, если они состоят из одних и тех же элементов. Порядок следования элементов в сравниваемых множествах значения не имеет (табл. 10.1).
Таблица 10.1. Примеры операции "равно"
"\ Операция "не равно" (<>). Два множества А и В считаются не равными, если они отличаются по количеству элементов или по значению хотя бы одного элемента (табл. 10.2).
Таблица 10.2. Примеры операции "не равно"
П Операция "больше или равно" (>=). Эта операция используется для определения принадлежности одного множества другому. Результат операции А>~В равен true, если все элементы множества В содержатся в множестве А. В противном случае результат равен false (табл. 10.3).
3 Операция "меньше или равно" (<=). Операция используется аналогично предыдущей операции, но результат выражения А<=В равен true, если все элементы множества А содержатся в множестве В. В противном случае результат равен false (табл. 10.4).
" V
Таблица 10.4. Примеры операции "меньше или равно"
О Операция in. Эта операция используется для проверки принадлежности какого-либо значения указанному множеству. Она обычно применяется в условных операторах (табл. 10.5).
Таблица 10.5. Примеры операции in
Операция in позволяет эффективно и наглядно производить сложные проверки условий, заменяя иногда десятки других операций. Например,
СЛОЖНОе условие if (a=l) or (а=2) or (a=3) or (a=4) or (a=5) then...
можно заменить более коротким выражением if a in [1.. 5] then...
Часто операцию in пытаются записать с отрицанием: х not in m. Такая запись является ошибочной, правильная инструкция имеет вид: not(x in m)
П Объединение множеств (+). Объединением двух множеств является третье множество, содержащее элементы обоих множеств (табл. 10.6).
Таблица 10.6. Примеры операции объединения множеств
П Пересечение множеств (*). Пересечением двух множеств является третье множество, которое содержит элементы,* входящие одновременно в оба множества (табл. 10.7).
Таблица 10.7. Примеры операции пересечения множеств
П Разность множеств (—). Разностью двух множеств является третье множество, которое содержит элементы первого множества, не входящие во второе множество (табл. Ю.8).
Таблица 10.8. Примеры операции разности множеств
Листинг 10.1 содержит небольшую программу, демонстрирующую операции над множествами. Множества чисел заполнены следующим образом: D1 -четными числами 2, 4, 6, 8; множество D2 — числами О, 1, 2, 3, 5; множество D3 — нечетными числами 1, 3, 5, 7, 9. После этого над множествами выполнены операции объединения, разности, пересечения.
; Листинг 10.1, Операции над множествами
type digits=set of 0.. 9;
var dl,d2,d3,d: digits;
begin
dl:=[2,4,6,8]; (заполнение множеств }
d2:=[0.. 3,5];
d3:-[l,3,5,7,9J;
d:=dl+d2; { объединение множеств dl и d2)
d:=d+d3; { объединение множеств d и d3 }
d:=d~d2; { разность множеств d и d2)
d:=d*dl; { пересечение множеств d и dl }
end.
!
Так как в Turbo Pascal отсутствуют средства ввода/вывода элементов множества, то действие программы можно проверить, исполняя ее по шагам и наблюдая текущие значения переменных dl, 62, d3, d в окне просмотра (см. приложение 1).
Тем не менее, нетрудно написать процедуру для вывода элементов множества. Например, процедура для вывода множества символов может иметь следующий вид:
type charset=set of char; procedure writeset(a:charset); var с:char; begin
for c:=chr(0) to chr(255) do
if с in a then write(c,' '); writeln; end;
Обратите внимание — значения элементов множества с помощью этой процедуры всегда будут выводиться в упорядоченном виде. Это не удивительно, т. к. в памяти они находятся в упорядоченном виде.
Рассмотрим следующий пример, демонстрирующий проверку принадлежности элемента множеству. Пусть требуется в предложении, введенном с клавиатуры, определить количество гласных букв. Программа для решения этой задачи приводится в листинге 10.2.
\ Л истин); 10.2. Подсчет количества гласных букв в предложении
const
glasn=[ 'а', 'е', 'и', 'о1, 'у'/ 'ьг', тэ', 'ю1, 'я',
•и' ' F ' ' И ' ' Г)' ' V ' ' W' ' Ч ' ' HV ' Я' 1 •
г\, И, г VI f w, J I Е* t -Э г № r /1J/
var s:string; p,i:integer; begin
write('Введите строку текста: '); readln(s);
p:=0;
for i:=l to length(s) do
if s[i] in glasn then p:=p+l;
writelnf'B строке ',р, ' гласных букв'); readln; end.
Комментарии j
В программе используется константа glasn, представляющая множество гласных букв. Проверка принадлежности символов предложения множеству гласных букв записывается операцией in. Разумеется, для решения этой задачи можно было бы записать вспомогательную строку из гласных букв и использовать функцию роз для поиска буквы в этой строке. Однако вариант с множеством предпочтительней, т. к. текст получился нагляднее, кроме того, проверка на принадлежность множеству выполняется намного быстрей, чем поиск символа в строке.
Формирование