Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основи програмування Паскаль.docx
Скачиваний:
51
Добавлен:
12.05.2015
Размер:
511.7 Кб
Скачать

20.2 Робота з рядками

Рядок - це масив символів, тобто елементів типу char. У Паскалі рядку відповідає тип данихString.

var Ім'я_рядка : string [Довжина];

Якщо довжина не зазначена, виділяється пам'ять під рядок до 255 символів.

var s1:string;

s2:string[20];

s3:array [1..20] of string;

Тут s2– рядок з 20 символів,s3– масив з 20 рядків, під кожну з яких буде виділено до 256 байт пам'яті (додатковий байт потрібний для зберігання довжини рядка).

Операції з рядками:

Привласнити рядку значення- оператор присвоювання.

s1:='А.І. Іванов';

s1[3]:=’В'; {символу привласнили символ!}

s2:='1999';

s3[1]:='Інформатика';

s3[2]:='';

Увести рядок із клавіатури: тільки операторreadln( тому що введення рядка повинен завершуватися натисканням Enter!).

Вивести рядок на екран: можна використовувати як,Writeтак іWriteln

s2:='SUMMA';

Write (s2) ; - буде виведено SUMMA

Writeln ('Сума':10); - буде виведено _ _ _ _ _ Сума

З'єднати 2 рядки- оператор додавання.

s1:='1999' + ' рік';

s3[3]:=s1+' '+s2;

Якщо при додаванні рядків перевищена максимальна довжина рядка, зайві символи відтинаються. Можна також використовувати стандартну функцію Concat.

Зрівняти 2 рядка:операції порівняння. Правила:

  • рядки рівні тільки при однаковому наборі символів і однаковій довжині;

  • інакше відбувається заелементне порівняння символів по їхніх кодах: '0'<'1'<...<'9'<'A'<...<'Z'<'a'<...<'z'<символи кирилиці

Стандартні підпрограми обробки рядків:

function Length (s:string):integer- визначити довжину рядка в символах;

function Copy (str:string; N,L:integer): string- повертає частина рядкаstrдовжиною L, починаючи з позиціїN;

procedure Insert (s0:string; var s: string; N: integer)- у рядокs вставляє рядокs0, починаючи з позиціїN;

procedure Delete (var s:string; N,L:integer)- у рядку s видаляєLсимволів, починаючи з позиціїN;

Function Pos (s0, s:string): integer- повертає позицію, починаючи з якої рядокs0утримується в рядкуsабо0, якщоs0не втримується вs;

Procedure Str (X: real; var s:string);

Procedure Str (X: integer; var s:string)- перетворить числоXу рядокs;

Procedure Val (s:string; var X: real; var error:integer);

Procedure Val (s:string; var X: integer; var error:integer);- перетворить рядокsу числоX. Якщо перетворити вдалося,error=0, інакшеerror=номеру першого непреобразуемого символу.

Наведених стандартних підпрограм досить для більшості нескладних завдань, пов'язаних з обробкою текстових даних. Розглянемо ряд типових завдань на прикладах.

Пр: Розглядаємо пропозицію на слова й виводимо кожне слово

var s,w:string;

p:integer;

begin

writeln ('Уведіть текст');

readln (s);

p:=1;

while p<>0 do begin

p:=pos (' ',s);

if p>0 then w:=copy (s,1,p-1)

else w:=s;

writeln (w);

delete (s,1,p);

end;

end.

Алгоритм роботи цієї програми дуже простий - доти, поки в рядку sє хоча б один пробіл, уся частина рядка до пробілу копіюється в строкову зміннуw(слово). Якщо пробілів уже ні, то весь рядок – це одне слово. Після обробки слова (у нашім випадку – це вивід його на новий рядок екрана операторомwriteln) оброблена частина рядка разом із пробілом віддаляються зs– щоб наступний крок циклу не знайшов те ж саме слово. Перший недолік такого підходу – не враховані зайві пробіли між словами. Позбудемося їх за допомогою наступного прикладу.

Пр: Видаляємо зайві пробіли між словами

{ . . . }

p:=1;

while p<>0 do begin

p:=pos (' ',s);

if p>0 then delete (s,p,1);

end;

if s[1]=' ' then delete (s,1,1);

if s[length(s)]=' ' then delete (s, length(s),1);

writeln (s);

Поки в рядку є два, що підряд ідуть пробілу, видаляємо один з них. Після цього залишається перевірити, немає чи на початку й кінці рядка по одному зайвому пробілу. Другий і більш істотний недолік наведених прикладів – проходи по рядкові кількаразові, тоді як розбір на слова можна зробити й за один цикл сканування рядка. Спробуємо реалізувати це в наступній програмі.

Пр.Розглядаємо пропозицію на слова за один цикл розбору.

var s,word:String;

c,c0:char;

i,l,start:integer;

inword:boolean;

begin

writeln ('Enter string:');

reset (input); readln (s);

s:=' '+s+' ';

l:=Length (s);

inword:=false;

for i:=2 to l do begin

c0:=s[i-1];

c:=s[i];

if (c0=' ') and (c<>' ') then begin

inword:=true;

start:=i;

end;

if (c=' ') or (c=#9) then begin

if inword=true then begin

word:=copy (s,start,i-start);

writeln ('''',word,''' is word');

end;

inword:=false;

end;

end;

end.

По суті справи, у нашої програми всього 2 стану – усередині слова й поза ним. Перемиканням станів управляє прапор inword. Номер символу, з якого починається чергове слово, запам'ятовується в зміннійstart. Програма не враховує розділові знаки й можливість поділу слів іншими символами, крім пробілу. Проте, позбувшись ще й від функціїcopy, що робить зайвий прохід у галузі рядка (наприклад,відразу жнакопичуючи словоwordу міру сканування), можна було б одержати дійсно ефективний алгоритм. Як звичайно, платою за ефективність є складність програми.

Пр. Працюємо з рядком як з масивом символів (уважаємо кіл-у пробілів у рядку)

var s:string;

k,i:integer;

begin

writeln ('Text?');

readln (s);

k:=0;

for i:=1 to length (s) do

if s[i]=' ' then k:=k+1;

writeln ('k=',k);

end.