1. Строковый тип данных

advertisement
1. Строковый тип данных
Строковый тип относится к числу структурированных типов. Строка –
это последовательность любых символов. Каждый символ занимает 1 байт
памяти (код ASCII). Количество символов в строке называется ее длиной.
Длина строки может находиться в диапазоне от 0 до 255. Особенностью строки
в языке программирования Паскаль является то, что с ней можно работать как с
массивом символов, с одной стороны, и как с единым объектом, — с другой.
Строковые величины могут быть константами и переменными.
Строковая константа есть последовательность символов, заключенная в
апострофы.
Например:
'это
строковая
константа',
‘272’;
str:=’Информация’;.
Описание строк
Строковая переменная описывается в разделе описания переменных
следующим образом:
Var <идентификатор> : string[<максимальная длина строки>];
Квадратные скобки после ключевого слова string обозначают, что
указание длины строки может отсутствовать. В этом случае длина строки по
умолчанию
будет
равна
255.
Соответствующая
данному
описанию
синтаксическая диаграмма представлена на Рис. 1. Синтаксическая диаграмма
описания строки.
Рис. 1. Синтаксическая диаграмма описания строки
Пример 1.1. Описания строк:
Var slovo: string;
name: string[20];
Строка slovo имеет максимальную длину 255 символов, name – 20.
Строка похожа на одномерный массив символов:
1

она имеет определенную длину (не больше некоторого числа);

к каждому символу можно обратиться по его номеру (как в
массиве): slovo[i] – это обращение к i-ому элементу строки slovo; name[5] –
указание на 5-й символ строки name; для вычисления номера символа
возможно использование выражения – slovo[k*2] (k должно быть переменной
целого типа).
По отношению к отдельному символу строки возможны все те же
операции, что и к переменной символьного типа Char: pred, succ, ord.
В памяти строка занимает на 1 байт больше своей длины, так как
существует символ с номером 0, в котором хранится длина строки. Операторы
WriteLn(Integer(slovo[0]))
и
WriteLn(Ord(slovo[0]))
обеспечивают
вывод
значения длины строки slovo. Если строковой переменной не присвоено
никакого значения, то ее текущая длина равна нулю. По мере заполнения
строки символами ее текущая длина возрастает, но она не должна превышать
максимальной по описанию величины. Если ввести больше символов, чем
значение n - максимально возможное количество, то строка будет равна первым
n символам, а остальные игнорируются.
Переменные типа String выводятся на экран монитора с помощью
стандартных процедур Write и WriteLn и вводятся с помощью стандартных
процедур Read и ReadLn. Т.е. строки вводятся и выводятся не поэлементно, как
массивы, а сразу целиком.
Операции
и
стандартные
подпрограммы,
применимые
к
строковому типу
В Паскале существует два пути обработки переменных типа String:

обработка всей строки как единого целого, т.е. единого объекта;

строка состоит из отдельных символов, т.е. элементов типа Char,
которые
при
обработке
доступны
каждый
рассматривается как составной объект.
2
в
отдельности.
Строка
1) Сцепление (Склеивание, +). Применяется для соединения строк в
одну:
1. ‘IBM’+’ ‘+’PC’=’IBM PC’
2. Var Str1, Str2, Str3:String [30];
…
Str1:=’Куй железо,’;
Str2:=’пока горячо’;
Str3:=Str1+’ ‘+Str2
Строка Str3 имеет значение ‘Куй железо, пока горячо’. В этом примере
итоговая строка может состоять максимум из 30 символов.
Функция Concat (S1, S2,… ,SN) используется для сцепления N строк в
одну.
Строки S1, S2, …, SN записываются одна за другой.
S:=concat(‘ли’,’ней’,’ка’); {S=’линейка’}
2) Сравнение строк. Сравнение строк происходит посимвольно слева
направо: сравниваются коды соответствующих символов до тех пор, пока не
нарушится равенство, при этом сразу делается вывод о знаке неравенства, либо
до тех пор, пока не закончится одна из строк. При этом большей считается
строка с большим числом символов. Символ считается больше, если больше его
номер в кодировочной таблице. Строки равны, если они совпадают по длине и
содержат одни и те же символы.
Можно использовать любые сравнения (>, <, =, <>, >=, <=) и их
комбинации в логических выражениях. Их результат – одно их двух значений:
True или False.
Пример 1.2. Использование сравнения строк.
Сравнение
Результат
Комментарий
‘пол’<’полка'
True
Длина второй строки больше
‘nomer3’<’nomer2’
False
Ord(‘3’) > Ord (‘2’)
‘Balkon’<’balkon’
True
Ord(‘B’) < Ord (‘b’)
‘A’<’1’
False
Ord(‘A’) > Ord (‘1’)
3
‘DOS’=’DOS’
True
Строки равны
3) Определение длины строки. Под длиной строки понимается
количество используемых символов, но она не может превышать максимально
возможной длины, которая указывается в описательной части. Для определения
реальной длины строки S используется функция Length(S). Результат —
значение целого типа.
S:=’компьютер’;
k:=length(S); {Длина строки равна 9}
Пример 1.3. Составить программу, которая выводит значение True,
если в строке цифра 1 встречается чаще цифры 2 и False – в противном
случае.
Program more1;
Var S:string[20];
i,k1,k2:byte;
Begin
ReadLn(S);
k1:=0;
{количество цифр ‘1’}
k2:=0;
{ количество цифр ‘2’}
For i:=1 to Length(S) Do Begin
If S[i]=’1’ Then k1:=k1+1
Else If S[i]=’2’ Then k2:=k2+1;
End;
WriteLn(k1>k2);
End.
Пример 1.4. Дано слово S, перед которым и после которого могут
стоять пробелы. Удалить из строки пробелы, если они присутствуют.
Program no_blank;
Var S,S1:string[20];
i:byte;
Begin
ReadLn(S);
{Ввод слова, возможно с пробелами}
S1:=’’;
{Слово без пробелов}
4
For i:=1 to length(s) Do
If S[i]<>’ ‘ Then S1:=S1+S[i];
WriteLn(S1)
End.
Пример 1.5. Подсчитать количество гласных латинских букв в строке.
Program letters;
Var s:string[50];
i,k:byte;
Begin
ReadLN(s);
k:=0;
For i:=1 to length(s) Do
If
(upcase(s[i])=’A’)
Or
(upcase(s[i])=’E’)
Or
(upcase(s[i])=’I’) Or (upcase(s[i])=’O’) Or (upcase(s[i])=’Y’) Or
(upcase(s[i])=’U’) Then inc(k);
WriteLn(k)
End.
Более эффективное решение задачи можно предложить с использованием
множеств (см. следующую главу).
4) Копирование. Функция Copy (S, k, N) – выделяет из строки S подстроку
длиной N, начиная с позиции k. Здесь k и N – целого типа. Исходная строка
после выполнения функции не меняется.
S:='победа’;
P:=copy(S,2,4); {P=‘обед’}
P:=copy(S,3,4); {P=‘беда’}
5) Поиск подстроки. Функция Pos (S1, S2) – обнаруживает первое
появление в строке S2 подстроки S1. Результат – номер позиции первого
символа, с которого начинается совпадение. Если совпадений не обнаружено,
то результат – 0.
S:=’задача’;
k:=Pos(‘дача’,S);
{3}
k:=Pos(‘дачи',S);
{0}
5
6) Удаление. Процедура Delete (S, k, N) удаляет N символов из строки S,
начиная с позиции k. Сама строка S изменяется, уменьшается текущая длина
строки.
S:=’рокот’;
delete(S,1,2); {S=’кот’}
7) Вставка подстроки. Процедура Insert (S1, S2, k) вставляет строку S1 в
строку S2, начиная с позиции k. Первая строка остается такой же как и была, а
вторая получает новое значение.
S:=’сода’;
Insert(‘воб’,S,2);
{S=’свобода’}
8) Перевод строкового значения в числовое, если данная строка
действительно является записью числа (целого или вещественного).
Число 13 и строка ‘13’ – это не одно и то же. Для работы с числами и
строками применяются две процедуры: val и str.
Процедура Val (S, N, Code) – преобразует строковое значение S в число N.
Значение переменной целого типа Code – признак ошибки при переводе,
содержит номер первого ошибочного символа. Если Code=0, то преобразование
прошло успешно.
Val(‘345’,N,k);
{N=345, k=0}
Val(‘345.67’,N,k);
{N=345.67, k=0}
Val(‘345,67’,N,k);
{k=4,
записи
чисел,
вещественных
т.к.
символ
«запятая»
разделителем
целой
и
недопустим
дробной
при
части
служит символ «точка»}
9) Перевод числового значения в строковое. Процедура Str (N, S) –
преобразует число N в строку S.
N:=345;
Str(N,S);
{S=’345’}
Пример 1.6. Что будет выведено на экран после выполнения следующих
действий?
S:=’космонавт’;
Delete(S,1,2);
Delete(S,4,3);
6
S:=copy(S,2,2)+S[1]+S[4];
write(s); {мост}
S[1]:=’р’;
write(S); {рост}
S[4]:=’а’;
write(S); {роса}
Пример 1.7. Даны две символьные строки A и B. Составить программу,
проверяющую, можно ли из букв, входящих в слово A, составить слово B
(каждую букву можно использовать не более одного раза и можно
переставлять).
ИНТЕГРАЛ -> АГЕНТ (да)
ИНТЕГРАЛ -> ГРАФ (нет)
Идея алгоритма: брать из второй строки (cтрока B) по букве и проверять,
есть ли данный символ в первой строке (строка А). Если есть, то удалить
символ из первого слова и перейти к следующему символу из слова В, а иначе
закончить просмотр – слово собрать нельзя, т.к. такого символа из В нет в
строке А.
Программа:
Program slovo;
Var A,B: string;
i,k: integer; fl:Boolean;
Begin
ReadLn(A); {ввод первого слова}
ReadLn(B); {ввод второго слова}
fl:=True;
{считаем, что составить слово можно}
i:=1;
While (i<=Length(B)) and fl Do Begin
k:=Pos(B[i],A);
If k<>0 Then Delete (A,k,1)
Else fl:=false; {Этого символа из строки В нет в строке А}
Inc(i);
End;
If fl then Writeln(‘Да’)
7
else Writeln(‘Нет’)
End.
Пример 1.8. Дана строка, состоящая из нескольких слов. Слова
разделены одним или несколькими пробелами. Выделить все слова текста и
записать их в массив. Вывести массив на экран.
Type Tstring=String[15];
Var
A:array[1..20] Of Tstring;
S:String;
k,i:Integer;
Begin
ReadLn(s);
s:=s+’ ‘; {добавляем в конец строки пробел, чтобы однотипным
образом выделять все слова, включая последнее слово}
While (s<>’’) And (s[1]=’ ‘) Do
Delete(s,1,1); {удаление пробелов из начала строки}
k:=0;
While s<>’’ Do Begin {пока строка не стала пустой}
k:=k+1;
A[k]:=Copy(s,1,Pos(‘ ‘,s)-1); {выделение слова}
Delete(s,1,Pos(‘ ‘,s)); {удаление выделенного слова из строки}
While (s[1]=’ ‘) And (s<>’’) Do
Delete(s,1,1); {удаление пробелов в начале строки}
End;
For i:=1 to k Do Writeln(a[i]);
End.
2. Множественный тип данных
Описание множеств
Множество – это совокупность однотипных значений, рассматриваемых
как единое целое. Элементы множества, в отличие от элементов массива, не
пронумерованы и не упорядочены. Нельзя обратиться к отдельному элементу
множества. Все действия выполняются над множеством целиком.
8
Описание множества:
Синтаксис описания множественного типа данных задается диаграммой,
изображенной на Рис. 1. Синтаксическая диаграмма понятия «множество»
Рис. 1. Синтаксическая диаграмма понятия «множество»
Тип элементов множества называется базовым. В качестве базового
может быть любой порядковый тип с элементами, для которых функция Ord
возвращает значения в диапазоне от 0 до 255.
Пример 2.1. Описания множеств:
Type Mn_Char=Set Of Char;
Var mnl:Set Of Char; {множество из различных символов}
mn2: Mn_Char;
{множество из различных символов}
mn3: Set Of 'A'..'Z'; {множество из больших латинских букв}
sl: Set Of Byte; {множество из целых чисел из диапазона от 0 до
255; тип Byte содержит целые числа от 0 до 255}
s2: Set Of 100..120; {множества целых чисел от 100 до 120}
Конкретные множества задаются перечислением элементов в квадратных
скобках. Элементы множества при перечислении разделяются запятыми. Если в
множестве имеется последовательность элементов, стоящих подряд в базовом
типе, то эти элементы можно не перечислять, а задавать в виде диапазона:
нижняя граница .. верхняя граница.
Примеры
конкретных
множеств:
[3,4,8,10],
[1..10,20..29],
[‘f’,’r’,’q’], [] – пустое множество.
Каждый элемент множества учитывается только один раз, остальные
повторные значения игнорируются. Не имеет значения порядок записи
элементов. Следующие множества считаются одинаковыми:
[1,2,3]=[3,2,1]
[2,3,5,2,3]=[5,3,2]
[1,2,3,4,5]=[1..3,4,5,2]
9
Пример 2.2.
Дано описание:
Type Digit = Set Of 1..5;
Var s:Digit;
Требуется перечислить количество различных множеств.
Ответ: Количество различных значений переменной s – 32:
[] – пустое множество;
[1], [2], [3], [4], [5] – одноэлементные множества;
[1,2],
[1,3],
[1,4],
[1,5],
[2,3],
[2,4],
[2,5],
[3,4],
[3,5], [4,5] – двухэлементные множества;
[1,2,3],
[1,2,4],
[1,2,5],
[1,3,4],
[1,3,5],
[1,4,5],
[2,3,4], [2,3,5], [2,4,5], [3,4,5] – трехэлементные множества;
[1,2,3,4],
[1,2,3,5],
[1,2,4,5],
[1,3,4,5],
[2,3,4,5]
–
четырехэлементные множества;
[1,2,3,4,5] – множество из всех элементов базового типа.
Операции над множествами
1) Объединением двух множеств называется множество, состоящее из
элементов, входящих хотя бы в одно из этих множеств. Знак операции: +.
[1,2,3,5]+[7,2,4,3]=[1,2,3,4,5,7,]
2) Пересечением двух множеств называется множество, состоящее из
элементов, одновременно входящих в оба множества. Знак операции: *.
[1,2,3,5]*[6,4,3,8]=[3]
10
3) Разностью называется множество, состоящее из элементов первого
множества, не входящих во второе. Знак операции: –.
А
В
[1,2,3,5,7]-[3,8,5,4]=[1,2,7]
[‘A’,’K’]–[‘B’,’D’]= [‘A’,’K’] – нет общих элементов.
4) Отношения между множествами:
A=B – множества А и В совпадают.
A<>B – множества А и В не совпадают.
A<B, A<=B – все элементы множества A принадлежат B.
A>B, A>=B – все элементы множества B принадлежат A.
Пример 2.3. Применение операций отношения.
[3,4,8,7]=[8,7,3,4,7] {True}
[1,3,5,6]<>[6,5,1,4] {True}
[3,5]<=[1,3,8,5,4] – проверка на вхождение 1-го множества во 2-е.
{True}
[1,8,7]>=[7,8,7] – проверка на вхождение 2-го множества в 1-е.
{True}
[]<=[1,2,3] {True}
5) Операция определения принадлежности элемента множеству
(Вхождения). Устанавливает связь между множеством и скалярной величиной.
Результат – истина, если скалярная величина входит в множество. Запись:
x in M, где x – скалярная величина, M – множество.
4 in [3,8,4,1] - true
‘a’ in [‘b’..’z’] - false
Операцию
проверки
принадлежности
исключения более сложных проверок.
Фрагмент программы:
Var ch:Char;
…
11
удобно
использовать
для
repeat
write (‘Продолжать? (Y/N)’);
ReadLn (ch);
Until (ch=’N’) or (ch=’n’) or (ch=’Y’) or (ch=’y’);
Последний оператор можно записать с использованием множества так:
Until ch In [’N’, ’n’, ’Y’, ’y’];
6) Ввод и вывод элементов множества. Значения множественного типа
нельзя вводить и выводить. Возможно только присваивание множеству
значений:
Пример 2.4. Ввод элементов множества.
…
Write(‘Введите размер множества’);
Read(N);
M:=[];
for i:=1 to N do
Begin
write(‘Введите ’i,’-ый элемент множества’);
ReadLn(c);
M:=M+[c]
end;
Задание. Приведите примеры правильных описаний переменных M и с.
Пример 2.5. Даны две символьные строки, содержащие латинские
буквы. Используя множеств, построить строку S3, содержащую общие
символы строк S1 и S2 в алфавитном порядке и без повторений.
Type Mset=set of ‘a’..’z’;
Var S1,S2,S3:string;
MS1,MS2,MS3:Mset;
c:char;
i:integer;
Begin
Writeln(‘Введите первую строку символов:’);
Read(S1);
Writeln(‘Введите вторую строку символов:’);
12
Read(S2);
MS1:=[];
MS2:=[];
For i:=1 to length(S1) do
MS1:=MS1+[S1[i]];
For i:=1 to length(S2) do
MS2:=MS2+[S2[i]];
MS3:=MS1*MS2;
S3:=’’;
For c:=’a’ to ‘z’ do
If c in MS3
then S3:=S3+c;
WriteLn(S3)
End.
Пример 2.6. Дано натуральное число n. Составить программу вывода
цифр в порядке убывания, не входящих в десятичную запись числа n.
Type Mn=Set Of 0..9;
Var s:Mn;
n:LongInt;
i:Integer;
Begin
WriteLn('Введите число ');
ReadLn(n);
s:=[0..9];
While n<>0 Do
Begin
s:=s-[n Mod 10]; (*Исключаем цифру.*)
n:=n Div 10;
End;
For i:=9 DownTo To 0 Do
If i In s Then Write(i:2);
WriteLn;
End.
13
Задание. Измените программу так, чтобы находились общие цифры в
записи m чисел.
Пример 2.7.
Подсчитать
количество
решений
ребуса
МУХА+МУХА=СЛОН. С использованием множественного типа данных
программный код получается более компактным.
Type Mn=Set Of 0..9;
Var i,j,cnt:Integer;
Sm,Se:Mn;
(*Из цифр числа формируем множество.*)
Procedure Digits_To_Set(t:Integer; Var S:Mn);
Begin
S:=[];
While t<>0 Do
Begin
S:=S+[t Mod 10];
t:=t Div 10;
End;
End;
(*Подсчитываем количество элементов в множестве.*)
Function Qw(S:Mn):Integer;
Var i,cnt:Integer;
Begin
cnt:=0;
For i:=0 To 9 Do
If i In S Then Inc(cnt);
Qw:=cnt;
End;
Begin
cnt:=0; (*Счетчик числа решений.*)
For i:=1000 To 4999 Do {Для данной задачи i может меняться
от 1234 до 4987. Объясните, почему?}
Begin
14
{*Результат - четырехзначное число, поэтому слагаемое не превышает
4999.*}
Digits_To_Set(i,Sm);
If Qw(Sm)=4 Then
Begin
{*Если
все
цифры
числа
различны,
то
выполняем
дальнейшие
вычисления.*}
j:=i+i;
Digits_To_Set (j,Se);
(*Числа
состоят
из
различных
цифр,
и
все
цифры
различны.*)
If (Sm*Se=[]) And (Qw(Se)=4) Then Begin
Inc(cnt);
Writeln (cnt,’-е решение: ’,i,’+’,i,’=’,j)
End
End;
End;
WriteLn(‘Всего ’,cnt,’ решений’);
End.
15
результата
Download