78210

Символьные переменные и строки. Организация и размещение в памяти. Процедуры и функции обработки строк

Лекция

Информатика, кибернетика и программирование

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

Русский

2015-02-07

1.15 MB

2 чел.

екция: Символьные переменные и строки. Организация и размещение в памяти. Процедуры и функции обработки строк  Страница. 11 из 11

Оглавление

[1] Оглавление

[2] Алгоритмы обработки символьной информации

[2.1] Операция присваивания

[2.2] Операция сцепления

[2.3] Операции отношения

[3] Функции и команды обработки строк

[3.1] Процедуры

[3.2] Функции

[4] Примеры программ  работы со строковыми данными

[5] Записи

[6] Множества

[7] Операции над множествами

[8] Контрольные вопросы

Комбинированный урок №12

Тема: Символьные переменные и строки. Организация и размещение в памяти. Процедуры и функции обработки строк

Цель: изучить приемы работы с данными типа «строка», приобрести навыки использования строковых процедур и функций Паскаля.

Алгоритмы обработки символьной информации

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

Символы с кодами от 0 до 127 построены по стандарту ASCII (American Standard Code for Information Interchange — Американский стандартный код обмена информацией,  читается  "аски"). Вторая половина таблицы (коды 128 ... 255) в нашей стране содержит русские буквы (кириллицу) и символы псевдографики.   Для того, чтобы определить по этим таблицам код того или иного символа, нужно сложить номер строки с номером столбца, в которых он расположен. Так, код цифры 5 равен 05+048 = 053.

Рисунок 1 - Стандартная кодировка фирмы IBM: а) для кодов 0...127; b) для кодов 128...255

Стандартный отечественный знакогенератор строится по рекомендациям Международного консультационного комитета по телеграфии и телефонии (МККТТ). Расположение символов во второй половине таблицы этого знакогенератора (рис.2,а) резко отличается от принятого фирмой IBM, что затрудняет использование зарубежного программного обеспечения на отечественных ПК. В связи с этим, стандартный (так называемый ГОСТовский) вариант кодировки часто заменяется альтернативным (рис.2,b), главное достоинство которого - расположение символов псевдографики на тех же местах, что и в знакогенераторе IBM. Недостаток такого знакогенератора заключается в том, что символы кириллицы не образуют непрерывный массив. Вариант, показанный на рис. 2,b в настоящее время получил наибольшее распространение на отечественных ПК. Именно на него рассчитаны практически все программы отечественного производства. Он стал фактическим стандартом для зарубежных фирм, изготовляющих ПК для экспорта в нашу страну.

Рисунок 2 - Варианты кодировки для кодов 128...255: а) по рекомендациям МККТТ; b) наиболее популярный

Символьная информация в алгоритмах и программах описывается данными двух типов: символьным и литерным. Они отличаются друг от друга тем, что значением символьной переменной является один символ, а литерной — строка символов.

Строка - это последовательность символов кодовой таблицы персональной ЭВМ. При использовании в выражениях строка-константа заключается в апострофы. Длина строки равняется количеству символов в этой строке и может изменяться от 0 до 255.

Для определения данных строкового типа используется идентификатор string, за которым следует заключенное в квадратные скобки значение максимально допустимой длины строки данного типа. Если это значение не указывается, то по умолчанию длина строки равна 255 байт. Переменную строкового типа можно задать через описание типа в разделе определения типов или непосредственно в разделе описания переменных.

Форма описания строковых данных:

Type имя типа=String [максимальная длина строки];

Var имя строковой переменной : имя типа;

или

Var имя строковой переменной : String [максимальная длина строки];

Пример: Type str=String[30];

Var C1,C2:str;

или

Var C3,C4:String[25];

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

Const S1 : String[4]=’ТБИП’;

S2 : String[4]=#107#116#102#44; {ktf.}

S3 : String[10]=’Да‘;

Знак # означает, что символ представляется его ASCII кодом.

Как и в массивах, к отдельным символам строки можно обратиться с помощью индексов в квадратных скобках: S1[2], S2[3]. При этом символ с нулевым индексом S1[0] содержит код, равный числу символов в строке S1.

Выражения, в которых операндами служат строковые данные, называются строковыми. Они состоят из строковых констант, переменных, строковых функций и знаков операций. Над строковыми данными допустимы операции присваивания, сцепления и отношения.

 

Типы данных, используемые для обработки символьной информации

 

Символьный Char

 a := ' f ' ;     b := '+' ;     c := '5' ; 
 If   a = ' ' then k := k + 1  

Литерный String

 t := 'Литерная величина' ; 
 f := ' ' ; (пустая строка) 

Для данных символьного и литерного типов применимы операции сцепки (соединения, конкатенации) и сравнения (<,   >,   <=,   >=,  =,   <>). Сравнивать можно строки разной длины. Сравнение осуществляется слева направо в соответствии с ASCII-кодами соответствующих символов.   Так, строка   "стол"   меньше строки   "стул",   строка   "teacher"  больше строки   "pupil"  , а строка   "пар"   меньше строки "парад".

Операция присваивания

Общий вид: Имя строковой переменной := строковое выражение;

Пример: Var S1 : String[2];

S2 : String[3];

. . .

S1 := ’No‘; S2 := ’Yes’;

S1 := S2;

Если длина строкового выражения превышает максимальную длину строковой переменной, то все лишние символы справа отбрасываются. Так, значение S1 в приведенном примере станет равным ‘Ye’. Отметим, что ввод и вывод значений строковых переменных с помощью операторов Read и Write осуществляются без заключения их в апострофы. Так, если в предыдущем примере вместо оператора S2:=’Yes’ мы воспользуемся оператором Read(S2), то на экране монитора необходимо набрать Yes, начиная с первой позиции.

Операция сцепления

Применяется для сцепления нескольких строк в одну результирующую строку. Для обозначения операции сцепления используется знак “+”. Длина результирующей строки не должна превышать 255. Например:

Program String_01;

Var C : Char;

S1:String[3];

S2:String[7];

Begin

Read(S1,C);

S2:=S1+C+’Yes’;

Write(‘S2=’,S2);

End.

Пусть была введена строка No i. Тогда после выполнения этой программы получим результат: S2=No i Yes.

Операции отношения

Над строковыми данными допустимы следующие операции отношения: =, <>, >, <, >=, <=. Эти операции имеют приоритет более низкий, чем операция сцепления, т.е. вначале всегда выполняются все операции сцепления, если они присутствуют, и лишь потом реализуются операции отношения. Сравнение строк с помощью операций отношения производится слева направо до первого несовпадающего символа. Строка считается больше, если в ней первый несовпадающий символ имеет больший номер в стандартной кодовой таблице.

Результат выполнения операций отношения над строковыми операндами всегда относится к булевскому типу и принимает значение True, если выражение истинно, и False, если выражение ложно. Строки считаются равными, если они полностью совпадают по текущей, а не по объявленной длине и содержат одни и те же символы.

Функции и команды обработки строк 

Процедуры 

Delete (Var S:String; Poz, L:Integer) видоизменяет строку S, стирая L символов, начиная с символа с номером Poz.

Пример:    Var S:String[10];

. . .

S:=’строка’;

Delete(S,2,4); {S=’са’}.

После стирания подстроки ее оставшиеся части как бы склеиваются. Если Poz = 0 или превышает длину строки S, то строка не изменится. Также не изменит длину строки значение L=0. При L больше остатка строки, будет удалена подстрока от Poz и до конца. Это используют для “подрезания” строк до заданной величины.

Insert (S1:String; Var S:String; Poz:Integer) вставляет подстроку S1 в строку S, начиная с позиции Poz.

Пример:  Var S1,S: String[40];

. . .

S:=’Начало-конец‘;

Insert(‘середина-‘, S, 8); { Имеем S=’Начало-середина-конец‘}.

Str (X [:Width [:dec]]; Var S:String) служит для преобразования числовых значений в строковые. Для целых значений можно задать только Width, для вещественных – либо оба поля (формат с фиксированной точкой), либо одно – Width (экспоненциальная форма). Если число имеет меньше знаков, чем дано в поле, то оно выравнивается по правому краю, пустое место заполняется пробелами. Можно задать Width отрицательным, в этом случае выравнивание происходит по левому краю, а излишек как бы стирается.

Пример:  Var S:String;

. . .

Str(4.53:8:2, S); {S=’ 4.53’}

Str(4.53:-8:2, S); {S=’4.53’}

Str(4.53:8:0, S); {S=’ 5’}

Str(1.234567:6:4, S); {S=’1.2346’}.

Val (S:String; Var V; Var ErrCode:Integer) преобразует числовые значения, записанные в строке S, в числовую переменную V. Если преобразование возможно, то переменная ErrCode равна нулю, в противном случае она содержит номер символа в строке S, на котором процедура застопорилась. Тип V должен соответствовать содержимому строки S.

Функции 

Length(S:String) : Byte возвращает текущую длину строки S. Результат имеет целочисленный тип.

Пример:  Var L:Byte;

. . .

L:=Length(S);

Concat(S1,S2,…,SN:String) : String выполняет слияние строк S1,S2,…,SN в том порядке, в каком они указаны в списке параметров.

Пример:  Var Ssum:String[50];

. . .

Ssum:=Concat(S1,S2,S3);

Если сумма длин строк в Concat превысит объявленную длину строки в левой части оператора присваивания, то излишек будет отсечен. Следует помнить, что вместо Concat можно пользоваться операцией сцепления. Например, Ssum:=S1+S2+S3;

Copy(S:String; Poz, L:Length) : String позволяет выделить из строки S последовательность из L символов, начиная с позиции Poz. Если Poz>Length(S), то функция вернет пустую строку, а если L больше, чем число символов от Poz до конца строки S, то вернется остаток строки S от Poz до конца.

Пример:  Var Ssum:String;

. . .

Ssum:=Copy(‘ABC***123’, 4, 3); {Ssum=’***’}

Ssum:=Copy(‘ABC’, 4, 3); {Ssum=’ ‘}

Ssum:=Copy(‘ABC***123’, 4, 11); {Ssum=’***123’]

Pos(S1, S:String) : Byte возвращает номер символа в строке S, с которого начинается включение в S подстроки S1. Если S не содержит в себе S1, то функция вернет 0. Недостатком функции Poz является то, что она возвращает ближайшую стартовую позицию S1 в S от начала строки, т.е. вызов

Var P:Byte;

. . .

P:=Poz(‘abc’, ’Nom abcabcabcfcd’);

завершит свою работу, вернув значение 5, хотя есть еще и 8, и 11.

UpCase(C:Ch) : Char преобразует строчную букву латинского алфавита в прописную, возвращая все остальные, в том числе и буквы русского алфавита, в исходном виде.

Pred(C:Char) : Char выдает предшествующий C символ.

Succ(C:Char) : Char выдает следующий за C символ.

Chr(X:Byte) : Char возвращает символ, код которого равен X.

Ord(C:Char) : Byte возвращает число, равное коду символа C. Учитывая, что текущая длина строки S содержится в S[0], она может быть определена следующим образом:

Var S:String;

L:Byte;

. . .

Read(S);

L:=Ord(S[0]);

Пример: Дана последовательность из 45 символов. Подсчитать в этой последовательности количество вопросительных и восклицательных знаков.

Program String 02;

Type St = String[45];

Var A : st;

i,K : Byte;

Begin

Writeln('ВВЕДИТЕ СТРОКУ СИМВОЛОВ:');

Readln(a);

K:=0;

For i:=1 to Length(a) Do

if (a[i]='!') Or (a[i]='?') Then K:=K+1;

Writeln('КОЛИЧЕСТВО СИМВОЛОВ ! и ? В СТРОКЕ= ',k);

End.

Примеры программ  работы со строковыми данными

Пример 1. Определить количество слов в заданном тексте.

Если слова в тексте разделены одним пробелом, то задача сводится к подсчету числа пробелов. Количество слов при этом равно числу пробелов плюс 1. Если же число пробелов между соседними словами произвольное, как обычно и бывает, то алгоритм усложняется. Рассмотрим оба варианта решения этой задачи.

Вариант 1. Слова в тексте разделены одним пробелом.

Тест

Данные

Результат

"Кот на крыше"

N=3

Program Probel; 

  Uses Crt; 

  Var Text      : String;  {заданный непустой текст}

     i, Number : Integer; {Number — количество слов в тексте}

     Letter    : Char;    {текущая буква }

BEGIN ClrScr;

  WriteLn('Введите текст :'); ReadLn(Text);

  Number:=1;

  For i:=1 to Length(Text) do {цикл по буквам текста}

  begin

    Letter:=Text[i];

    If (Letter = ' ') then Number:=Number+1;

  end;

  WriteLn('О т в е т : количество слов в тексте равно ', Number);

END.

Вариант 2. Слова в тексте разделены произвольным количеством пробелов.

Тест

Данные

Результат

"Кот на крыше"

N=3

Program KolSlov;

  Uses Crt;

  Var Text      : String;  {заданный текст}

     i, Number : Integer; {Number - количество слов в тексте}

     Flag      : Boolean;

     Letter    : Char;    {текущая буква }

BEGIN

  ClrScr;

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

  ReadLn(Text);

  Number := 0; Flag := TRUE;

  For i := 1 to Length(Text) do {цикл по буквам текста}

   begin

     Letter := Text[i];        {текущая буква текста }

     If (Letter <> ' ') and Flag

       then Number := Number+1;

     Flag := (Letter=' ')     {(Letter=' ') — логическое выражение,}

   end;                       {принимающее значения TRUE или FALSE }

  WriteLn;

  WriteLn('О т в е т : количество слов в тексте равно ', Number); ReadLn

END.

 

Пример 2. Определить, является ли заданное слово "перевёртышем" (слово называется "перевёртышем", если совпадает с собой после переворачивания).

Система тестов

N теста

Данные

Результат

1

Slovo = ''казак''

Otvet = ''Перевертыш''

2

Slovo = ''коза''

Otvet = ''Не перевертыш''

Program TurnOver;

  Uses Crt;

  Var Slovo    : String;

     Dlina, i : Integer;

     Flag     : Boolean;

BEGIN

  ClrScr;

  Write('Введите слово : ');  ReadLn(Slovo);

  Dlina:= Length(Slovo);

{Сравниваются пары букв: первая буква с последней, вторая буква с предпоследней и т.д.} 

  i:=1;  Flag := TRUE;  

  While (i <= Dlina/2) and Flag do        {цикл до первой несовпавшей }

   begin                                 {пары букв (если такая есть)}

     Flag := (Slovo[i]=Slovo[Dlina-i+1]);

     i := i+1

   end;

  WriteLn; Write( 'О т в е т : слово ', Slovo);

  If Flag then WriteLn(' — перевертыш. ')

         else WriteLn(' — не перевертыш');

  ReadLn

END.

Пример 3. B заданном тексте одно заданное слово везде заменить на другое заданное слово такой же длины.

Тест

Данные

Результат

Текст

Слово1

Слово2

''2sinx+siny''

''sin''

''cos''

''2cosx+cosy''

Эта программа, использующая стандартную функцию  Pos , не требует,  чтобы длины  заменяемого и вставляемого слов были одинаковыми.

Program Replace;

  Uses Crt;

  Var Text, Slovo1, Slovo2 : String;

     i, DlinaSlova, P     : Integer;

BEGIN ClrScr;

  Write('Введите строку : '); ReadLn(Text);

  Write('Какое слово заменить ? '); ReadLn(Slovo1);

  Write('На какое слово заменить ? '); ReadLn(Slovo2);

  WriteLn; WriteLn('О т в е т : ');

  WriteLn('Исходный текст: ', Text); DlinaSlova:=Length(Slovo1);

  DlinaSlova:=Length(Slovo1);

  P:=Pos(Slovo1,Text); {номер позиции, с которой в строке Text     }

                      {в первый раз встречается подстрока Slovo1  }

  While P>0 do         {цикл продолжается до тех пор,пока подстрока}

                      {Slovo1 встречается в строке Text           }

  begin                

    Delete(Text, P, DlinaSlova); {удаление подстроки Slovo1, начинаю-}

                                 {щейся с позиции P, из строки Text  }  

    Insert(Slovo2, Text, P);  {вставка подстроки Slovo2  }

                              { в строку Text с позиции Р}

    P:=Pos(Slovo1, Text); {номер позиции, с которой подстрока Slovo1} 

                          {встречается в строке Text в очередной раз}

  end;

  WriteLn('Новый текст: ', Text); 

  ReadLn

END.

  

Пример 4. Заданную последовательность слов переупорядочить в алфавитном порядке (то есть выполнить лексикографическое упорядочение).

Тест

Данные

Результат

Words=(''стул'', ''гора'', ''яма'', ''стол'')

  Words=("гора", "стол", "стул",  "яма")

Program LexOrder;

  Uses Crt;

  Var Words        : Array[1..10] of String; {массив слов}

     Tmp          : String;       {Tmp — вспомогательная переменная}

     i, j, NWords : Integer;      {NWords — количество слов}

BEGIN

  ClrScr;

  Write('Количество слов в тексте — ');

  ReadLn(NWords);

  For i := 1 to NWords do

   begin Write(i, '-ое слово : ');    

         ReadLn(Words[i])

   end;

  For i := 1 to NWords-1 do {лексикографическое упорядочение слов}

   For j := i+1 to NWords do

     If Words[i]>Words[j] then

       begin

          Tmp := Words[i]; Words[i]:=Words[j]; Words[j]:=Tmp

       end;

  WriteLn;  WriteLn('О т в е т');

  WriteLn('Лексикографически упорядоченный массив слов:');

  For i := 1 to NWords do Write(Words[i], ' ');

  WriteLn; ReadLn

END.

 

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

Система тестов

Номер

теста

Проверяемый случай

Данные

Результат

1

При просмотре линейной записи слева направо первой встречается закрывающая скобка

''a)b+1(''

''Нет баланса''

2

Первой встречается открывающая скобка, но число открывающих и закрывающих скобок не совпадает

''(a+b))''

''Нет баланса''

3

Есть баланс скобок

''(a+b/(c*d))''

''Есть баланс''

Program Balance;

  Uses Crt;

  Var S              : String;

     Dlina, Flag, i : Integer;

BEGIN ClrScr;

  GotoXY(15, 5);

  Write('Введите линейную запись математической формулы :'); 

  GotoXY(32,7); ReadLn(S);

  i:=1; Flag:=0; Dlina:=Length(S);

  While (Flag>=0) and (i<=Dlina) do

   begin

     If S[i] = '(' then Flag:=Flag + 1;

     If S[i] = ')' then Flag:=Flag - 1;

     i:=i+1

   end;

  GotoXY(32, 9); WriteLn('О т в е т');

  GotoXY(15,11);

  If Flag=0 then Write('Есть баланс ') else Write('Нет баланса ');

  WriteLn('открывающих и закрывающих скобок');

  ReadLn

END

Записи

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

Запись - это структурированный тип данных, состоящий из фиксированного числа компонентов одного или нескольких типов, называемых полями записи. Определение типа записи начинается идентификатором Record и заканчивается зарезервированным словом end. Между ними заключен список компонентов, называемых полями, с указанием имен полей и  типа каждого поля. Структура объявления типа записи такова:

Type <имя типа> = Record 

<имя поля1>: <тип компонентов>;

<имя поляN>: <тип компонентов>;

End;

VAR <имя переменной>: <имя типа>;

Пример описания записи:

Type Car=Record

Number:Integer;

Marka:String[20];

FIO:String[40];

Address:String[60];

End;

Var Mashina, Mash : Car;

В данном примере была объявлена запись с именем Car, у которой имеется 4 поля: номер, название марки машины, ФИО владельца и его адрес.

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

Например, доступ к полям записи Car осуществляется как: Mashina.Marka, Mashina.FIO, Mashina.Number. Составное имя можно использовать везде, где допустимо применение типа поля. Для присваивания полям значений используется оператор присваивания, например:

Mashina. Number:=1645365;

Mashina.Marka:=’Volvo’;

Mashina.FIO:=’Иванов И.И.’;

Mashina. Address:=’ул.Пушкина 12-30’;

Составные имена можно использовать в операторах ввода-вывода:

Read (Mashina. Number, Mashina. FIO, Mashina. Address);

Write(Mashina. Number:4, Mashina. FIO:12, Mashina. Address:25);

Допускается применение оператора присваивания и к записям в целом, если они имеют один и тот же тип. Например, Mash:=Mashina;

После выполнения этого оператора значения полей записи Mash станут равны значениям соответствующих полей записи Mashina.

В ряде задач удобно пользоваться массивами из записей. Их можно описать следующим образом:

Type Car=Record

Number:Integer;

Marka:String[20];

FIO:String[40];

Address:String[60];

End;

Var Mashins : array [1..20] of Car;

Обращение к полям такой записи имеет громоздкий вид. Для решения этой проблемы в языке Паскаль предназначен оператор With, который имеет следующий формат:

With <переменная типа запись> do <оператор>;

Один раз, указав переменную типа запись в операторе With, можно работать с именами полей как с обычными переменными,например:

With Mashina do

Begin

Number:=164536l;

Marka:=’Volvo’;;

FIO:=’Иванов И.И’;

Address:=’ул.Пушкина 12-30’;

End;

Множества

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

Все элементы множества должны принадлежать одному из скалярных типов, кроме вещественного. Этот тип называется базовым типом множества. Базовый тип задается диапазоном или перечислением. Область значений типа множество – набор всевозможных подмножеств, составленных из элементов базового типа. В выражениях на языке Паскаль значения элементов множества указываются в квадратных скобках:[1,2,3,4], [‘a’,’b’,’c’], [‘a’..’z’]. Если множество не имеет элементов, оно называется пустым и обозначается, как [ ]. Количество элементов множества называется его мощностью.

Формат записи множественных типов:

Type   <имя типа> = set of <элемент 1,…., элементN>;

Var <идентификатор, ….> :  <имя типа>;

Можно задать множественный тип и без предварительного описания:

Var <идентификатор, …> :  set of <элемент1, …>;

Пример:

Type Simply  = set of  ‘a’ ..’h’;

Number = set of  1..31;

Let = set of (‘a’,’e’,’i’,’o’,’u’,’y’);

Var Pr : Simply;

N : Number;

L : Let;

Letter : set of char; {определение мн-ва без предварительного описания в разделе типов}

В данном примере  переменная Pr может принимать значения символов латинского алфавита от ‘a’  до  ‘h’; N – любое значение в диапазоне 1..31; L – один из символов перечисленного множества; Letter – любой символ. Попытка присвоить другие значения вызовет программное прерывание.

Количество элементов множества не должно превышать 256, соответственно номера значений базового типа должны находиться в диапазоне 0..255. Контроль диапазонов осуществляется включением директивы {$R+}. Объем памяти, занимаемый одним элементом множества, составляет 1 бит.

Объем памяти для переменной типа множество вычисляется по формуле:

 Объем памяти = (Max DIV 8) – (Min DIV 8) + 1, где Max и Min – верхняя и нижняя границы базового типа.

Операции над множествами

При работе с множествами допускается использование операций отношения “=”, “<>”,  “>=”,  “<=”, объединения, пересечения, разности множеств и операции in. Результатом выражения с применением этих операций является значение True или False.

Операция “равно” (=). Два множества А и В считаются равными, если состоят из одних и тех же элементов. Порядок следования элементов в сравниваемых множествах значения не имеет.

Значение А

Значение В

Выражение

Результат

[1,2,3,4]

[‘a’, ’b’, ’c’]

[‘a’..’z’]

[1,2,3,4]

[‘c’, ‘a’]

[‘z’..’a’]

A=B

A=B

A=B

True

False

True

Операция “не равно” (<>). Два множества А и В считаются не равными, если они отличаются по мощности или по значению хотя бы одного элемента.

Значение А

Значение В

Выражение

Результат

[1,2,3]

[‘a’..’z’]

[‘c’..’t’]

[3,1,2,4]

[‘b’.. ‘z’]

[‘t’..’c’]

A<>B

A<>B

A<>B

True

True

False

 Операция “больше или равно” (>=). Операция “больше или равно” (>=) используется для определения принадлежности множеств. Результат операции А >=В равен True, если все элементы множества В содержаться в множестве А. В противном случае результат равен False.

Значение А

Значение В

Выражение

Результат

[1,2,3,4]

[‘a’..’z’]

[‘z’,’x’,’c’]

[2,3,4]

[‘b’.. ‘t’]

[‘c’,’x’]

A>=B

A>=B

A>=B

True

True

True

Операция “меньше или равно” (<=). Эта операция используется аналогично предыдущей операции, но результат выражения А<=В равен True, если все элементы множества А содержаться во множестве В. В противном случае результат равен False.

Значение А

Значение В

Выражение

Результат

[1,2,3]

[‘d’..’h’]

[‘a’,’v’]

[1,2,3,4]

[‘z’.. ‘a’]

[‘a’,’n’,’v’]

A<=B

A<=B

A<=B

True

True

True

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

Значение А

Значение В

Результат

2

v

X1

if A in [1,2,3] then..

if A in [‘a’..’n’] then..

if A in [X0,X1,X2,X3] then..

True

False

True

При использовании операции in проверяемое на принадлежность значение и множество в квадратных скобках не обязательно предварительно описывать в разделе описаний. Операция in позволяет эффективно и наглядно производить сложные проверки условий, заменяя иногда десятки других операций. Например, выражение if(a=1) or (a=2) or (a=3) or (a=4) or (a=5) or (a=6) then…можно заменить более коротким выражением if a in [1..6] then… .

Часто операцию in пытаются записать с отрицанием: X NOT in M. Такая запись является ошибочной, так как две операции следуют подряд; правильная инструкция имеет вид:  NOT (X in M). 

Объединение множеств (+). Объединением двух множеств является третье множество, содержащее элементы обоих множеств.

Значение А

Значение В

Выражение

Результат

[1,2,3]

[‘A’..’D’]

[]

[1,4,5]

[‘E’.. ‘Z’]

[]

A+B

A+B

A+B

[1,2,3,4,5]

[‘A’..’Z’]

[]

Пересечение множеств (*). Пересечением  двух множеств является третье множество, которое содержит элементы, входящие одновременно в оба множества.

Значение А

Значение В

Выражение

Результат

[1,2,3]

[‘A’..’Z’]

[]

[1,4,2,5]

[‘B’.. ‘R’]

[]

A*B

A*B

A*B

[1,2]

[‘B’..’R’]

[]

Разность множеств (-). Разностью двух множеств является третье множество, которое содержит элементы первого множества, не входящие во второе множество.

Например:

Значение А

Значение В

Выражение

Результат

[1,2,3,4]

[‘A’..’Z’]

[X1,X2,X3,X4]]

[3,4,1]

[‘D’.. ‘Z’]

[X4,X1]

A-B

A-B

A-B

[2]

[‘A’..’C’]

[X2,X3]

Результат операций над двумя множествами можно наглядно представить с помощью закрашенных частей двух кружочков:

   Объединение                             Пересечение                            Разность

Использование в программе данных типа set дает ряд преимуществ: значительно упрощаются сложные операторы if , увеличивается степень наглядности программы и понимания алгоритма решения задачи, экономятся память, время компиляции и выполнения.

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

Пример. Операции над множествами.

uses crt;

type digits=set of 0..20;

var m1,m2,m0,l,f,t:digits;

i:integer;

ch1,ch2:byte;

{процедура формирования множества k,состоящих из элементов множества m, кратных ch}

procedure Form_Set(ch:byte;m:digits;var k:digits);

var i:integer;

begin

k:=[];

for i:=0 to 20 do if (i in m) and (i mod ch=0) then k:=k+[i];

end;

{процедура вывода множества set_}

procedure out_set(set_:digits);

var i:integer;

begin

 for i:=0 to 20 do

  if (i in set_) then write(i:3);

 writeln;

end;

Begin

 clrscr;

{формирование множества 1}

 writeln('Введите последовательность чисел [0..20] (признак конца - 0)');

 m0:=[];

read(i);

if i<>0 then m0:=m0+[i];

while (i<>0) do

 begin

   read(i);

   m0:=m0+[i]

 end;

 {формирование множества 2}

 write ('vvedite chislo ');  read(ch1);

 Form_Set(ch1,m0,m1);

 m2:=[2,4,6,8,10,12,14,16,18,20]; {формирование множества 3}

 l:=m1+m2;

 f:=m1*m2;

 t:=m1-m2;

 {вывод множеств}

 writeln;

 writeln('set m0:');   out_set(m0);

 writeln('set m1:');   out_set(m1);

 writeln('set m2:');     out_set(m2);

 writeln('set m1+m2:');  out_set(l);

 writeln('set m1*m2:');  out_set(f);

 writeln('set m1-m2:');  out_set(t);

 end.

Протокол работы:

Введите последовательность чисел [0..20] (признак конца - 0)

4 3 5 15 18 16 3 0

Введите число 3

Множество m0:  0 3 4 5 15 16 18

Множество m1:  0 3 15 18

Множество m2:  2 4 6 8 10 12 14 16 18 20

Множество m1+m2:  0 2 3 4 6 8 10 12 14 15 16 18 20

Множество m1*m2:  18

Множество m1-m2:  0 3 15

Контрольные вопросы

  1.  Как описываются строковые данные?
  2.  Чему равна максимальная длина строковой переменной?
  3.  Какие операции допустимы над строковыми данными, их приоритет, какие выражения называются строковыми?
  4.  Какие стандартные процедуры и функции существуют в Паскале для работы со строковыми данными?
  5.  Что такое запись? Основные операции с записями.
  6.  Оператор With для обращения к полям записи. Формат записи.
  7.  Что такое множество? Какие операции используются над множествами?


 

А также другие работы, которые могут Вас заинтересовать

5761. Основа архитектуры документ\представление 721.5 KB
  Основа архитектуры документ/представление Создание различных типов документов Шаблоны однодокументных приложений Шаблоны многодокументных приложений Место объекта-приложения в архитектуре документ/представление Роль...
5762. Основы программирования под Windows с использованием MFC 208 KB
  Программирование под Windows с использованием MFC MFC - это базовый набор (библиотека) классов, написанных на языке С++ и предназначенных для упрощения и ускорения процесса программирования под Windows. Перед изучением библиотеки MFC и ее испол...
5763. Работа с файловой системой 124.5 KB
  Работа с файловой системой Файловые системы делятся на несколько типов, в каждой из которых используются одни и те же методы обращения и работы с файлами, дисками и папками. Ниже приведены некоторые типы файловых систем: FAT - самая старая и знакома...
5764. Управление памятью в среде Windows 87 KB
  Управление памятью С приходом 32-разрядной Windows управление памятью стало гораздо более приятным, чем раньше. Огромная путаница с сегментами и другими параметрами управления памятью в 16-разрядном режиме сегментной архитектуры Intel-процессоров по...
5765. Краткое описание основных производственных, энергетических и транспортных цехов 101.5 KB
  Краткое описание основных производственных, энергетических и транспортных цехов Агломерационный цех Агломерационный цех построен в 1938 г. Восстановление аглофабрики производилось в следующем порядке: агломашина № 2 - 1945г. агломашина № 1 - 1949 г. а...
5766. Процессы и потоки 188.5 KB
  Процессы и потоки Основные понятия Процесс (process) - это отдельная исполняемая программа с используемой ею памятью и другими выделяемыми ей ресурсами. Многозадачность (multitasking) - это способность операционной системы выполнять несколько п...
5767. Подбор и расчет параметров ленточного конвейера 390.5 KB
  Введение Машины непрерывного транспорта являются неотъемлемой частью современных систем комплексной механизации погрузочно-разгрузочных, транспортных и складских работ. Большинство таких машин применяется как для непосредственного транспортирования ...
5768. Расчет экономической эффективности предприятия ЗАО Ладушка 277 KB
  Введение: В своей курсовой работе по экономике предприятия, я отдала предпочтение предприятию специализирующегося на выпечке хлебобулочных изделий, посчитав это занятие прибыльным и беспроигрышным. Ведь хлеб-это товар первой необходимости, а, след...