Мета роботи
У лабораторній роботі вивчаються основні поняття, операції та функції, які пов¢язані з опрацюванням символьних послідовностей змінної довжини (рядків) засобами алгоритмічної мови Object Pascal.
Основні теоретичні відомості
Оголошення та присвоєння значень даним рядкового типу
Дані рядкового типу – це масив (послідовність) будь-яких символів.
Константа рядкового типу – це послідовность символів, які беруться в апострофи. Наприклад:
‘Одеська Національна Академія Зв’язку’,
‘Чорноморець’.
Змінна рядкового типу при оголошенні має стандартне ім’я string. Значенням змінної рядкового типу є константа цього ж типу. Кожний символ такої змінної має ім´я, яке складається з імені цієї змінної, у квадратних дужках коло якого стоїть індекс символу в рядку, і звертатися до елемента послідовності можна так само, як до елемента символьного масива. Наприклад, якщо name1:=’Pascal’, то name2:=name1[4] має значення ‘ c ’.
Для зберігання змінної рядкового типу надається кількість байтів, яка дорівнює максимальній кількості символів у цьому рядку плюс один. Байт з номером 0 (ноль) містить число, дорівнюване фактичній кількості символів у рядку.
|
|
Рядковий тип даних дозволяє розміщувати в одній і тій самій змінній послідовності символів різної довжини, наприклад:
Var name:string[15];
…
Begin
…
name:=’Object Pasсal’;
…
name:=’Delphi’;
…
end;
У цьому фрагменті програми змінну оголошено рядок символів з максимальною довжиною 15. Першим значенням цієї змінної (name- 1) є рядок ‘Object Pasсal’ з фактичною довжиною 13 символів (враховуючи прогалину поміж символами). Друге значення (name- 2) – рядок ‘Delphi’ – має довжину 6 символів.
У пам’яті комп’ютера змінна name в обох варіантах значень займатиме 16 байт і розміщуватиметься згідно зображенню рис.8.1.
Номер байта | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
name-1 | 13 | O | b | j | e | c | t | P | a | s | c | a | l | |||
name-2 | 6 | D | e | l | p | h | i |
Рисунок 8.1 – Розміщення символів у даних рядкового типу
Байт з номером 0 містить фактичну поточну довжину символьної послідовності, записаної у name (спочатку – 13, а остаточно – 6). Байти, що стоять після останнього символу поточного значення name (позначено сірим кольором на рисунку) містять випадкові двійкові коди, які можна назвати “сміття”.
Щоб надати змінній name “порожнього” значення, слід використати опе-ратор :
name:=’’;
Найбільша припустима довжина змінної рядкового типу, очевидно, дорівнює максимальному числу, яке може бути записане у байт за номером 0, тобто числу 255. Якщо рядкова змінна має цю максимальну довжину її можна не писати в оголошенні змінної:
|
|
Var s:string;
Зауваження. Змінні рядкового типу можуть бути короткими чи довгими. В першому випадку довжина змінної не може бути більша за 255 символів, а у другому вона обмежена об’ємом пам’ті у 2 Гбайт. Для коротких рядків передбачено спеціальний тип shortstring або string [255], а для довгих (залежно від версії Delphi) такі назви типу: longstring, widestring, ansi-string, widechar.
Операції над string-даними
1) Конкатенація (зчіплювання) кількох символьних величин. Знак “плюс” позначає операцію, операндами якої можуть бути дані типу char або string, а результатом – string-рядок, дорівнюваний послідовності операндів. Наприклад, нехай змінні s1,s2 та s3 оголошено як string, а змінна t має тип char i містить символ тире, тоді внаслідок виконання операторів
t:=’–‘;
s1:=’Одеса ’;
s2:=’ місто-герой’;
s3:=s1+c+s2;
змінна s3 набуде значення ‘Одеса – місто-герой’.
2) Логічні операції (порівняння символьних величин). Принцип порівняння аналогічний до порівняння слів за алфавітом. Cимвольна послі-довність s1 вважається меншою за символьну послідовність s2, якщо перший символ s1 є менший за перший символ s2 за своїм кодом-номером у ANSI-таблиці. Якщо ж перші символи рівні, порівнюються їхні другі символи і так далі. Наприклад, логічний вираз ‘1 долар’<>’1$’ матиме значення True, а вираз ‘1 долар’=’1$’ – значення False.
Основні функції для роботи зі string-даними
1) Copy – виокремлення підпослідовності з послідовності символів.
Function Copy(s:string; i:integer; n:integer):string;
Тут s – вхідна послідовність;
і – індекс початку підпослідовності, яку треба виокремлювати;
n – довжина (число символів) виокремлюваної послідовності.
Наприклад,
Var str1,str2:string;
Begin
str1:=’Object Pasсal’;
str2:=Copy(str1,8,6);
Значенням str2 буде підпослідовність зі str1, яка розпочинається у 8-й позиції і має довжину 6. Отже, Str2=’Pasсal’.
2) Pos – визначення позиції початку заданої підпослідовності у заданій послідовності:
Function POS(p:string;s:string):byte;
Результатом цієї функції буде індекс початку підпослідовності р у рядку s; якщо ж р не міститься в s, результатом є нуль. Тип результату – byte – це невід’ємне ціле число від 0 до 255. Наприклад, POS(‘Pasсal’,’Object Pasсal’) дорівнюватиме 8;
3) Length – визначення фактичної довжини послідовності символів:
Function Length(s:string):byte;
Ця функція переводить у числову форму байт довжини string-послідовності і повертає знайдене число як свій результат.
Наприклад:
Var str:string[30];dlina:integer;
Begin
Str:=’Місто Одеса’;
Dlina:=Length(str); // значенням змінної dlina буде 11
…
3) StrToInt(s) – переведення рядка символів s в ціле число.
4) IntToStr(n) – переведення цілого числа n в рядок.
5) StrToFloat(s) – переведення рядка s в дійсне число.
6) FloatToStr(x) – переведення дійсного числа х в рядок.
Стандартні процедури для роботи з даними рядкового типу
1) Delete – вилучення підпослідовності з заданої послідовністі:
Procedure Delete(var s:string; k:integer; n:integer);
Вилучає зі string-змінної s задану кількість n символів, починаючи з символу, який стоїть в s у заданій позиції k. Після вилучення довжина s зменшується на n символів.
Наприклад: …
s:= ‘Object Pasсal’;
Delete(s,1,6); // тепер дорівнюватиме ’ Pasсal’
2) Insert – уставлення підпослідовності в задану послідовність:
Procedure Insert(p:string; var s:string; k:integer);
Уставляє задану рядкову величину р у string-змінну s, починаючи із заданої позиції k змінної s.
Наприклад: …
str1:=’Object’;
str2:=’Pascal’;
str1:=str1+’’;
Insert(str1,str2,1); // тепер str2=’Object Pascal’
3) Val – переведення символьного запису числа в його числовий формат:
Procedure Val(s:string; var x:<числовий тип>; var ier:integer);
Тут s – символьний запис числа, х – число-результат типу real чи integer, ier – код завершення процедури, якщо перетворення відбулось успішно, то ier дорівнюватиме нулю і буде іншим, якщо у символьному записі числа містились помилки.
|
|
Наприклад: …
var s1,s2: string; f:integer; h:real; ier:integer;
…
begin s1:=’125’; s2:=’–1. 253E2’;
Val(s1,f,ier); // змінна f міститиме ціле число 125
Val(s2,h,ier); //змінна h міститиме дійсне число –125,3
4) Str – переведення чисел у символьні записи:
Procedure Str (x:<числовий тип>; var s:string);
Забезпечує переведення числа х у його символьний запис s. Наприклад, після виконання Str(12,s) string-змінна s матиме значення ‘12’.
Приклади програм
Приклад1
Завдання. Написати проект програми, що вводить три string-рядки з 20-ти або меншого числа елементів і визначає однакові символии між кожною парою рядків та однакові символи з усіх трьох рядків.
Форму проекту та результати роботи програми наведено на рис.8.2.
Рисунок 8.2 – Форма проекту прикладу 1
Текст програми:
………………….
implementation
{$R *.DFM}
Type tstr=string[20];
// підпрограма визначення однакових символів поміж двох рядків
procedure Spsimv(s1,s2:tstr;var s:tstr);
var i,dlina,po,ps:integer;
Begin
s:='';
dlina:=length(s1);
for i:=1 to dlina do
begin
ps:=pos(s1[i],s2);
if ps<>0 then
begin
po:=pos(s1[i],s);
if po=0 then s:=s+s1[i];
end;
end;
end;
// підпрограмма до кнопки “Старт”
procedure TForm1.Button1Click(Sender: TObject);
var s1,s2,s3,s12,s13,s23,s123:tstr;
Begin
// введення значень рядків
s1:=edit1.text;
s2:=edit2.text;
s3:=edit3.text;
// визначення однакових символів поміж кожною парою рядків
Spsimv(s1,s2,s12); edit4.text:=s12;
Spsimv(s1,s3,s13); edit5.text:=s13;
Spsimv(s2,s3,s23); edit6.text:=s23;
// визначення однакових символів у трьох рядках
Spsimv(s12,s23,s123); edit7.text:=s123;
end;
……….
end.
3.2 Приклад 2
Завдання. Ввести рядок зі значеннями кількості доларів (через прогалину). Вивести у компонент Memo масив відповідних значень у гривнях.
Форму проекту та результати роботи програми наведено на рис.8.3.
Текст програми:
unit Unit1;
……..
Implementation
{$R *.DFM}
Type s60=string[60];
// підпрограма-функція вилучення початкових прогалин рядка
function del_n(s1:s60):s60;
Begin
while (pos(' ',s1)=1)and (length(s1)>0) do
delete(s1,1,1);
|
|
del_n:=s1;
end;
// підпрограма-функція виокремлення першого” слова” з послідовності
function slovo(s:s60):s60;
var p:integer;
Begin
p:=pos(' ',s);
if p=0 then slovo:= s
else slovo:= copy(s,1,p-1);
end;
// підпрограма-процедура переведення “слова” з доларів у гривні
procedure dol_gr(sdol:s60; koef:real; var sgr:s60);
var dol,gr:real; ier:integer;
begin
delete(sdol,1,1); // вилучення символу ‘ $’
val(sdol,dol,ier); // переведення рядкового значення в числове
gr:=dol*koef; // перерахунок числового значення в гривні
str(gr:10:2,sgr); // перетворення числового значення в рядкове
sgr:=sgr+' грн.';
end;
// підпрограма до кнопки “Перерахунок у гривню“
procedure TForm1.Button1Click(Sender: TObject);
var sv,sr,sg:s60; k,dd:integer;
begin sv:=edit1.text; // читання введеного рядка
k:=strtofloat(Edit2.text); // читання курсу долару
sv:=del_n(sv); // вилучення початкових прогалин рядка
while length(sv)>0 do
begin
sr:=slovo(sv); // виокремлення першого “слова” з послідовності
dol_gr(sr,k,sg); // переведення “слова” з доларів у гривні
memo1.lines.add(sg); // виведення результату
delete(sv,1,length(sr)); //вилучення першого “слова” з послідовності
sv:=del_n(sv); // вилучення початкових прогалин рядка
end;
end;
End.
3.3 Приклад 3
Завдання.Написати програму, яка вводить два string-рядки та визначає, який з них є довший. якщо перший рядок є довший ніж другий, то програма додає у другий рядок символ ‘#’ до довжини першого, якщо другий рядок є довший за перший, − додає у перший рядок символ ‘$’ до довжини другого.
Форму проекту та результати роботи програми наведено на рис.8.4.
Рисунок 8.4 – Форма проекту до прикладу 3
Текст програми:
………………………….
implementation
{$R *.DFM}
// підпрограма до кнопки “Перерахунок у гривню“
procedure TForm1.Button1Click(Sender: TObject);
Var a,b:string[10];
dla,dlb,i:integer;
Begin
// читання рядків
a:=edit1.text;
b:=edit2.text;
// визначення довжини рядків
dla:=length(a);
dlb:=length(b);
if dla>dlb then
// додавання у другий рядок символів ‘#’
for i:=dlb+1 to dla do
begin
b:=b+'#';
edit3.text:=b;
end
else if dla<dlb then
// додавання у перший рядок символів ‘$’
for i:=dla+1 to dlb do
begin
a:=a+'$';
edit3.text:=a;end;
end;
end.
4 Контрольні запитання
1 Що таке байт довжини? Який номер у цього байта?
2 Скільки байтів займає величина, оголошена як string[5]?
3 Запишіть оператор чи оператори, котрі дозволяють ввести рядок з 8 символів.
4 Запишіть оператор, котрий запише у рядкову послідовність S2 початок рядкової змінної S1, аж до її 4-го символу включно.
5 Відомо, що змінна К містить слово “авто”. Запишіть оператор конкатенації, котрий надасть змінній значення “автозавод”.
6 Яку процедуру слід використати, щоб перевести ціле число k у символьну форму? Запишіть її виклик.
7 Яку процедуру слід використати, щоб перевести дійсне число D у символьну форму і записати у рядкову послідовність S? Запишіть її виклик.
8 Яку процедуру слід використати, щоб перевести символьний запис цілого числа, котрий зберігається у string–змінній Т, у числову форму? Запишіть її виклик.
9 Яку процедуру слід використати, щоб перевести символьний запис дійсного числа, котре зберігається у рядковій змінній S, у числову змінну К? Запишіть її виклик.
10 Яка функція переводить у числову форму байт довжини рядкової послідовності й повертає знайдене число як свій результат? Запишіть її.
11 Чому дорівнює значення функції Length(‘’)?
12 Яку функцію треба використати, щоб перевести символьний запис в ціле число?
Лабораторне завдання
1 Розробити проект форми та програми алгоритмічною мовою Object Pascal для виконання індивідуального завдання відповідно до варіантів у середовищі Delphi.
2 Оформити протокол для виконання лабораторної роботи.
3 Занести результати обчислень до протоколу.