69114

Рядки. Поняття рядка та оголошення змінних рядкового типу. Операції над рядками та рядкові вирази. Процедури та функції обробки рядків

Лекция

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

Один з різновидів одновимірних масивів — масив символів, або рядок, — посідає особливе місце у багатьох мовах програмування. І це не випадково, адже алгоритми перетворення рядків застосовуються для вирішення вкрай широкого кола задач: редагування та перекладу текстів, алгебричних перетворень формул...

Украинкский

2014-09-30

79 KB

2 чел.

Лекція 23. Тема: Рядки. Поняття рядка та оголошення змінних рядкового типу.

                             Операції над рядками та рядкові вирази. Процедури та функції обробки рядків.

План:

1. Рядки

2. Поняття рядка та оголошення змінних рядкового типу

3. Операції над рядками та рядкові вирази

4. Процедури та функції обробки рядків

1. Рядки

Один з різновидів одновимірних масивів — масив символів, або рядок, — посідає особливе місце у багатьох мовах програмування. І це не випадково, адже алгоритми перетворення рядків застосовуються для вирішення вкрай широкого кола задач: редагування та перекладу текстів, алгебричних перетворень формул, криптоаналізу, в інформаційно-пошукових системах, електронних словниках тощо. Більш того, відомо, що будь-який алгоритм можна подати у вигляді алгоритму перетворення рядків. У мові Раsсаl з усіх можливих типів масивів лише для рядків було зарезервовано стандартний структурований тип даних — string, а також розроблено потужну бібліотеку процедур і функцій обробки даних рядкового типу.

2. Поняття рядка та оголошення змінних рядкового типу

Рядок - це скінченна послідовність символів, яку можна розглядати як особливу форму одновимірного масиву. Нагадаємо, що одна з характеристик масиву - це кількість його елементів, яка є фіксованою величиною і визначається під час оголошення масиву. Рядок як масив символів теж характеризується довжиною, тобто кількістю символів. Але для рядка розрізняють поняття загальної та поточної довжини. Загальна довжина рядка визначається об'ємом оперативної памя’ті, що була надана рядку під час його оголошення. Поточна довжина рядка визначається кількістю символів у ньому в конкретний момент виконання програми, вона ніколи не перевищує загальної довжини. Спосіб визначення поточної довжини рядка залежитъ від способу оголошення відповідної рядкової зміної. У мові Раsсаl є два способи оголошення змінної-рядка:

оголошення зміної спеціального структурованого типу даних string;

оголошення змінної типу символьного масиву.

У разі оголошення рядка як змінної типу string його поточна довжнна зберігається в елементі з нульовим індексом. У цей елемент записується символ, код якого дорівнює значенню довжини. При виведенні рядка користувач не побачитъ цього символу, але у програмі можна прочитати або змінити його значення. Але не слід забувати, що нулъовий елемент рядка — це символ, а не число, і тому для отримання числового значення довжини рядка слід застосовувати вбудовану функцію ord(<символ>), а для запису довжини - вбудовану функцію chr(<число>).

У разі оголошення рядка як змінної типу символьного масиву його поточна довжина фіксується спеціальним символом, розташованим після останнього інформаційного символу рядка. Цей спеціалъний символ називається символом кінця рядка або нуль-символом (NULL-символом), його ASCII-код дорівнює 0, а позначається цей символ лексемою #0. Зазначимо, що лише до тих рядків, які є зміними типу string, можуть бути застосовані бібліотечні функції обробки рядків, а також операції присвоєння, об'єднання та порівняння. Обробка символьних масивів є ніяк не легшою за обробку одновимірних масивів. Тому надалі розглядатимемо лише ті змінні-рядки, що оголошені як змнні типу string.

Зауважимо, що поточна довжина рядка визначається автоматично під час його ініціалізації. Зокрема, при введеннні рядка з клавіатури його довжина дорівнюватиме кількості символів, введених до натискання клавіші Enter.

Настав час навести синтаксис оголошення змінної типу string:

<ім’я зміної>:string[<загальна довжина рядка>]:

Як бачимо, вказувати значення загальної довжини рядка не обов'язково. Отже, припустимим є скорочений синтаксис оголошення зміної рядкового типу:

<ім'я знінної>:string;

Оскільки будь-який символ займає один байт пам'яті, то максимальне значения загальної довжини рядка буде обмежене максимальним значенням, яке можна записати в одному байті. Отже, максимальне значення довжини рядка становить 255 символів. Якщо під час оголошення рядкової змінної не вказана загальна довжина рядка, то за замовчуванням вона вважається рівною 255. Обсяг пам’яті, що виділяється для збереження значення рядкової зміної, буде на один байт більшим від вказаної в оголошенні загальної довжини рядка, оскільки для збереження значення його поточної довжини потрібний додатковий байт пам’яті.  

Наведемо приклади оголошень зміних рядкового типу.

const length=50;

var

    str:string;             {резервується 256 байт}

    name:string[15];  { резервується 16 байт }

    address:string[length]; { резервується 51 байт }

Як і елементи будь-якого масиву, символи рядка зберігаються у поряд розташованих комірках оперативної пам'яті. Припустимо, що до щойно оголошеної зміної name було введено з клавіатури рядок символів ‘Turbo Pascal’. Зображення значення зміної name в оперативній пам'яті буде таким, як показано на рис. 7.21.

 T

 u

 r

 b

 o

 P

 a

 s

 c

 a

 l

 0          1          2          3          4          5         6           7          8         9          10         11        12       13         14        15

                                                               Індекси елементів рядка

                                     Рис.7.21. Зображення рядка в оперативній пам’яті

В елементі з ідексом 0 зберігається символ, код якого дорівює поточній довжині рядка 'Turbo Pascal', тобто 12. До елементів рядка з індексами від 13 до 15 можна звертатися: їм можна присвоїти значення будь-якого символу або прочитати їх. Але під час виведення рядка символи, що їх індекси перевищують поточну довжину, не відображатимуться.

Крім змінних рядкового типу використовуються рядкові константи, які записуються в одиночних лапках, наприклад: 'Turbo Pascal'. Довжина рядкової константи визначається за допомогою функції length, шо її буде розглянуто в розділі 7.3.3. Цю саму функцію можна застосувати і для визначення довжини рядка, яка є значенням рядкової зміної.

3. Операції над рядками та рядкові вирази

У мові Раsсаl змінні типу string можна обробляти двома способами. Перший спосіб дає можливість розглядати рядок як цілісний об'єкт, другий — обробляти його як об'єкт, що складається з окремих символів, тобто з елементів типу char. Перший способ надає можливість за одну операцію присвоювати рядковій змінній значення рядка символів, виконувати об'єднання декількох рядків тощо. Другий спосіб забезпечує доступ до окремих символів рядка за їх индексами - аналогічно тому, як отримується доступ до елементів одновимірного масиву. Для доступу до символу рядка застосовують операцію ідексування:

<ім’я зміної рядкового типу>[<індекс символу>]

Отже, розглянемо означені в мові Раsсаl операції над даними рядкового типу. Це такі операції, як присвоення, об'єднання та порівняння рядків.

Присвоєння рядків

Вираз рядкового типу можна присвоїти змінній рядкового типу. Символи рядка, що є значенням рядкового виразу, присвоюються відповідним елементам зміної. Якшо довжина рядкового виразу більше загальної довжини змінної, присвоюються лише перші символи в межах означеної кількості. Під час операції присвоєння неявно модифікується нульовий елемент змінної, що набуває нового значення. Нехай змінна str означена як string[5]. Після присвоєння str:=’Kiyv’ значення символів рядка стануть такими: str[0]=chr(4), str[1]=’K’, str[2]=’i’, str[3]=’y’, str[4]=’v’. Якщо згодом виконати оператор присвоения str:=’Ukraine’, то символи ‘n’ в рядку str будуть втрачені.

Об'єднання рядків

Над рядковими змінними означена операція об'єднання, або конкатенації, яка дозволяє дописати один рядок в кінець іншого. Ця операція позначаєтъся символом «+». Під час конкатенації рядків поточна довжина рядка, до якого приєднується інший рядок, збільшується на довжину рядка, що додається. Збільшення довжини об'єднаного рядка здійснюється тілъки у заданих під час оголошення межах. Наступний приклад демонструє конкатенацію рядків та ситуацію, коли така операція виконується некоректно через накладені на загалъну довжину рядка обмеження.

Приклад 7. 18

Ввести рядки, об'єднати їх та вивести результат.

Program ex7_17;

var

   name:string[5];

   address:string[12];

   str1:string[7];

   str2:string;

   identif:string[15];

begin

   writeln(‘enter name’);

    readln(name);

    writeln(‘length of name=’, ord(name[0]));

    writeln(‘enter address’);

    readln(address);

    writeln(‘length of address=’, ord (address[0]));

    writeln(str1);

    writeln(‘length of  str1=’,ord(str1[0]));

    str2:=name+’ ‘+address;

    writeln(str2);

    writeln(‘lenght of str2=’, ord(str2[0]));

    identif:=name+’ ‘+address;

    writeln(identif);

    writeln(‘lenght of identif=’, ord(identif[0]));

    readln;

end.

На рис. 7.22 зображені результати виконання програми ех7_17. 3 цього рисунка видно, що під час об'єднання рядків завдовжки 3,1 та 12 символів у рядок, для якого виділено тільки 7 байт пам'яті (str1:=name+’ ‘+address;), праві символи рядка address втрачаються. Під час конкатенації рядків завдовжки 3 та 12 символів у рядок завдовжки 255 символів (str2:name+’ ‘+address;) немає жодних втрат.

Порівння рядків

Для даних рядкових типів означено всі наявні в мові Раsсаl операції порівння: =, <>, <, >, <=,>=. Щоб зрозуміти принцип дії цих операцій, нагадаємо спочатку правило порівняння даннх символьного типу. Кожному символу відповідає унікальний код у таблиці символів ASCII. 3 двох снмволів більшим вважається той, код якого більший. Рядки - це послідовності символів, і порівняння рядків виконується як серія порівнянь тих символів рядків, що мають однакові індекси. Інакше кажучи, при порівнянні рядків враховуєтъся їх лексикографічний, або алфавітний, порядок. А саме, спочатку порівнюються перші символи рядків (символи з індексами 1). Якщо ці символи відмінні, то більшим вважається той рядок, перший символ якого більший. В іншому разі порівнюються другі символи рядків. Якщо і другі символи рядків виявляються однаковими, то порівнюються треті символи рядків тощо. Отже, якщо а і b - деякі рядки, а і - це такий найменший індекс, що а[і] <> b[i], то рядок а вважаєгься більшим у тому разі, коли [а] > b[i], і навпаки. Постає питания: а коли такого індекса і, що а[і] <> b[і], не існує? Тоді можливі два варіанти: коли довжина рядків однакові, то рядки вважаютъся равними, а коли довжина рядків різна, то більшим вважається довший рядок. Для прикладу наведемо декілька істинних булевих тверджень.

‘Borland’ < ‘Turbo’

‘Borland Pascal’<’Turbo’

‘Turbo Pascal’>’Turbo’

‘Borland’>’Borisov’

‘Borland’<’borland’

‘borland’<’борланд’

Істинність цих тверджень випливає зокрема з того, що АSCII-коди великих літер менші за АSCII-коди маленьких літер, коди літер латиниці менші за коди літер кирилиці, а літери того самого регістру з тієї самої абетки розташовані в таблиці АSCII-кодів у алфавітному порядку.

4. Процедури та функції обробки рядків

Потужна бібліотека процедур і функцій, призначених для роботи з рядками в мові Раsсаl, значно полегшує розв'язання задач, пов'язаних з обробкою текстів. У цьому розділі розглянуто синтаксис і семантику рядкових процедур і функцій, а також розв'язано за їх допомогою практичну задачу. Одразу зазначимо, що для введення та виведення рядків застосовують стандартні процедури введення-виведення даних. Наприклад, для рядкової змінної s можна виконувати процедури readln(s) та writeln(s). Використання процедур введення та виведення рядків було проілюстровано в прикладі 5. У даному розділі ці процедури не розглядаються.

Процедури обробки рядків

Процедура видалення дає можливість видалити певну кілъкість символів з рядка, починаючи із заданої позиції. Її прототип такий:

Delete(var s: String; Index: Integer; Cout:Integer);

Вказана процедура має три параметри: s - рядок, з якого видаляються символи; Index - ідекс символа, з якого починається видалення; Cout — кількість символів, що мають бути видалені.

Під час видалення довжина рядка автоматично змєншується на кількістъ видалених символів. Символи, що містилися в рядку праворуч від зони видалення, автоматично переставляються на позиції видалених символів, тобто здійснюється серія операцій присвоєння s[i]:=s[i+с], де s - змінна рядкового типу; с - кількість символів, що видаляються; і - лічильник. Наведена нижче програма видаляє з рядка 'children' 3 останіх символи.

var str:string;

begin

      str:=’children’;

      Delete(str,6,3);

      Writeln(str);     {виведено ‘child’}

end.

Зворотна операція вставки символів у рядок реалізуєтъся процедурою Insert, що її параметрами є два рядки и одне ціле число:

Insert(Source:String; var s: String; Index: Integer);

Зміст параметрів процедури є таким: Source - рядок, що вставляється в інший рядок; s – рядок, куди здійснюється вставка; Index - номер позиції, з якої вставка починається.

Після виконання вставки символів довжина рядка автоматично збільшується в межах заданої в оглошенні довжини. Якщо вставка здійснюється всередину рядка, то місце для підрядка вивільняється за рахунок зсуву символів рядка вправо, тобто виконується серія присвоєння вигляду s[i+с]:=s[i]. Як приклад наведемо програму, що вставляє у рядок ‘frnd’ симвили ‘ie’.

var str1,str2:string;

begin

      str1:=’frnd’;

      str2:=’ie’;

      insert(str2,str1,3);

      writeln(str1);           {виведено ‘friend’}

end.

Рядки, що складаються із символів цифр, можна перетворити на числа і навпаки. Для цього використовують процедури Val i Str, прототипи яких наведено нижче.

Val(s:String; var v; var Code; Integer);

Процедура має такі параметри: s — рядок, що перетворюється на число; v — змінна типу integer або геа1, до якої число буде записано; Сodе — змінна цілочисленого типу, яка визначає успішність перетворення (Сodе = 0) або містить код помилки (Соde<>0). Помилка виникає тоді, коли рядок s не є символьним записом числа. У такому разі значення змінної Соdе дорівнює номеру першого помилкового символу. Як приклад наведемо програму, що перетворює рядок на значення цілочисленної змінної Num.

const st:=’150’;

var num, code:integer;

begin

     Val(st, num,code);

     writeln(num);    {виведенол 150}

end.

Процедура Str є зворотною до функції Val. Наведемо її прототип:

Str(x[:Width [: Decimals ]]; var s:string);

У процедурі означено такі параметри: х — змінна цілого або дійсного типу, значения якої перетворюватиметься на рядок; Width - необов'язковий параметр, що визначає кількість символів у створюваному рядку; Decimals - необов'язковий параметр, що визначає кількість символів після десяткової точки; s - рядок, який утворюється. Наведемо код, що перетворює число на рядок за допомогою функци St.

var N:read;

  st:string;

begin

  n:=160.236;

  str(n:5:2,st);

  writeln(st);    {виведемо 160.24}

end.

функції обробки рядків

За допомогою бібліотечних функцій, що мають параметри типу string, можна визначити поточну довжину рядка, скопіювати рядки та їх підрядки, визначити позицію входження підрядка в рядок та виконати конкатенацію рядків.

 Отже, наведемо прототип функції копіювання підрядка в новий рядок:

Copy(s: String; Index: Integer; Cout: Integer): String;

Параметри функції: s — рядок, який копіюють; Indeх — позиція, з якої розпочинається копіювання; Сount - кількість символів, що копіюються. Якщо загальна довжина рядка, який утворюється, є меншою за кількість символів, що копіюються, то у вихідному рядку будуть тільки перші символи з числа тих, які треба скопіювати. Наведемо приклад:

var s: string;

begin

  s: ‘Turbo Pascal’;

  s:=Copy(s,7,6);    {результат – рядок символів ‘Pascal’}

end.

Для визначення поточної довжини рядка s крім операції ord(s[0]) можна застосувати функцію Length(s). Її прототип є очевидним:

Length(s: string): Integer;

Операції лексичного аналізу потребують визначення наявності певних символів у рядках. У мові Раsсаl означена функція, що повертає номер позиції першого входження символу або підрядка в рядок. Прототип функції такий:

Pos(Substr: string; s: string): byte;

У функції означено два параметри: Substr — підрядок, позицію першого входження якого необхідно повернути; s - рядок, до складу якого має входити підрядок. Якщо потрібного підрядка в рядку немає, то функція повертає нуль. Наведена нижче програма всі пробіли на початку рядка s замінює цифрами 0.

var s: string;

begin

    s:=’  123.5’;

    while Pos(‘ ‘, s)>0 do

      s[Pos(‘ ‘, s)]:=’0’;

end.

Наведемо приклад застосування процедур та функцій обробки рядків.

Приклад 7.19

Будь- який текстовий редактор може виконати операцію заміни у тексті, всіх входжень одного рядка іншим. Поставимо задачу замінити всі слова ‘child’ у введеному користувачем рядку словом ‘children’, розуміючи під словом деяку послідовність символів, не обов'язково оточену пробілами. Зауважимо, що наведена нижче  програма ех7_18 розв'язує дану задачу не найоптимальнішим способом, вона призначена для демонстрації можливостей якомога більшої кількості бібліотечних процедур і функцій.

Алгоритм заміни в рядку кожного слова 'child' словом 'children'

1. Ввести рядок.

2. Створити новий порожній рядок

3. Поки у вхідному рядку міститься підрядок 'child', повторювати дії, зазначені у пунктах 3.1-3.4.

3.1. Визначити позицію поточного слова ‘child’.

3.2. Вставити підрядок 'геп' у вхідний рядок на визначену позицію.

3.3. Приєднати до нового рядка копію вхідного рядка, починаючи з першого символа до слова ‘children’ включно.

3.4. Видалити із вхідного рядка скопійований підрядок

4. Після завершення циклу приєднати до нового рядка символи вхідного рядка, що залишилися після видалення.

Program ex7_18;                  {заміна слів у тексті}

 var s: string;                        {початковий рядок}

       n: integer;                      {позиція в рядку}

       snew: string;                  {новий рядок}

 begin

    writeln(‘To replace “child” with “children” ’);

    writeln(‘input string’);

    readln(s);

    snew:=’ ‘;   {порожній рядок, до якого подаватимуться підрядки із вставленими словами}

   while Pos(‘child’, s)<>0 do

     begin    {поки в рядку трапляються символи’child’}

                  {визначити позицію поточного слова‘child’}

       n:=Pos(‘child’, s);

                   {ввести ‘ren’ у рядок після слова ‘child’}

       insert(‘ren’,s,n+5); {до нового рядка додати частину рядка s, від його початку до слова ‘children’}

       snew:=snew+Copy(s, 1, n+5); {видалити з рядка s скопійований рядок}

       delete(s, 1, n+5);

    end;

   snew:=snew+s;  {приєднати рядок після останнього ‘child’}

   writeln(‘output string’);

   writeln(snew);

end.

Контрольні питання

1. Рядки

2. Поняття рядка та оголошення змінних рядкового типу

3. Операції над рядками та рядкові вирази

4. Процедури та функції обробки рядків


 

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

55828. Правописание О-Е после шипящих и Ц в окончаниях существительных 54.5 KB
  По вертикали: 4душем 5свечой 6больницей Время на выполнение упражнения 5 минут. На выполнение задания не более 5 минут. Письменное выполнение упражнения в тетрадях. На выполнение задания 8 минут.
55829. Синтаксис и пунктуация 53 KB
  Цель: Обучить детей правильно разбирать предложения и ставить знаки препинания. Закрепить умения детей разбирать предложения по частям речи. Разберём по членам предложения и частям речи.
55830. Русский язык и культура речи 57.5 KB
  Язык – это совокупность средств речевого взаимодействия людей. Язык является орудием мышления. Русский язык (в мире 500 млн. человек знают русский язык) Язык это форма существование национальной культуры, проявление духа нации.
55833. Квітучий сад. Конспект заняття з малювання для старших дошкільнят 34 KB
  Так узимку дерева кущі й квіти спали і снилися їм сни як і вам уночі. Як ви гадаєте що снилося деревам Про що вони мріяли Діти фантазують: деревам снилися тепла весна спів птахів вітерець який бавиться листячком веселий дощик. Так дерева мріяли про весну. Це було ось так: Спали дерева у мареві синім Вітер гойдав їхні віти Снились деревам у сні тім чарівнім Листя зелене та квіти.
55834. Сады мира - Gardens of the world 1000.5 KB
  Цель: познакомить школьников с произведениями ландшафтного искусства садоводов Великобритании; развивать самообразовательную, коммуникативную, творческую компетентности...
55836. Let’s meet with the sportsmen of wild nature on Safari 81 KB
  A Magic Wand (a pen) will help you to write an e-mail to your favourite Ukrainian sportsman or a sportswoman about sportsmen of wild nature and about sport activities. Use the information from your word bubbles.