Тема уроку: "Алгоритми роботи з рядковими величинами."

Мета уроку: Навчити розв'язувати задачі з використанням рядкових величин.
Тип уроку: Практичний.

На початку уроку бажано провести опитування (в письмовому чи усному вигляді) по матеріалах попереднього уроку (означення та опис рядкових величин, стандартні процедури та функції для роботи з рядковими величинами). Далі рекомендується розглянути деякі задачі, що виконують обробку рядкових величин.
Задача №383.
Умова: У даному тексті всі послідовності крапок замінити на одну крапку.
Для розв'язку цієї задачі пропонується організувати цикл перегляду кожного елементу рядка (краще за допомогою циклу з передумовою), причому, якщо буде знайдена група крапок, вилучити її повністю, а потім вставити на це ж місце тільки одну крапку. Для вилучення групи крапок можна скористатися кількома способами. Наприклад, підрахувати їх кількість, а потім всі вилучити.
Ми пропонуємо вилучати всі крапки, доки не зустрінеться символ, що не являється крапкою.

Program Example_383; 
Uses crt; 
Var i:word; {i - змінна циклу} 
St:string; {St - даний текст} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln (St); 
i:=1; 
While i<=length(St) do 
Begin 
While St[i]='.' do Delete(St,i,1); 
Insert('.',St,i); 
i:=i+1; 
End; 
Writeln ('Результуючий рядок: '); 
Writeln (St);  
Readkey; {Затримка зображення на екрані} 
End. 
 
Задача №384(2).
Умова: Дано деякий текст, у якому є хоча б одна кома. Визначити порядковий номер останньої коми в тексті.
Для пошуку останньої коми в тексті необхідно організувати цикл перегляду рядка з кінця до початку, тобто від останнього символу рядка з номером length(St) до першого. В зв'язку з тим, що ми не знаємо, якою за номером буде кома, краще це зробити командою повторення з передумовою. Цикл завершить свою роботу при досягненні позиції, в якій знаходиться кома (за умовою вона обов'язково є в тексті). Значення змінної циклу і буде номером шуканої позиції.
Програма, що реалізує описаний алгоритм, має наступний вигляд:
Program Example_384_2; 
Uses crt; 
Var i:byte; {i - змінна циклу} 
St:string; {St - даний текст} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln(St); 
i:=length(St); 
while St[i]<>',' do i:=i-1; 
Writeln ('Номер позиції останньої коми в тексті ',i);  
Readkey; {Затримка зображення на екрані} 
End. 

Задача №386.
Умова: Дано деякий текст. Створити новий текст, який утворено із даного читанням з кінця до початку.
Для реалізації даної задачі знов, як і в попередньому випадку, пройдемо рядок з кінця до початку, виконуючи конкатенацію кожного наступного символу до нового рядка.
Програма, що реалізує описаний алгоритм, має наступний вигляд:

Program Example_386; 
Uses crt; 
Var i:byte; {i - змінна циклу} 
St,Rez:string; {St - даний текст, Rez -  
результуючий (перегорнутий)  
рядок} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln (St); 
Rez:=''; {Очищення рядка} 
For i:=length(St) downto 1 do 
Rez := Rez+St[i]; 
Writeln ('Результуючий рядок: '); 
Writeln (St);  
Readkey; {Затримка зображення на екрані} 
End. 

Задача №387.
Умова: Перевірити, чи однаково читається дане слово зліва направо і навпаки.
Для розв'язку цієї задачі можна використовувати попередню задачу, як підзадачу, тобто спочатку отримати новий рядок, який являється оберненим відносно даного, а потім порівняти даний та отриманий рядки. Якщо вони співпадають, слово являється паліндромом (читається в обох напрямках однаково, наприклад, "дід", "потоп", "Пилип" тощо), в протилежному випадку - ні.
Програма, що реалізує описаний алгоритм, має наступний вигляд:

Var i:byte; {i - змінна циклу} 
St,Rez:string; {St - даний текст, Rez -  
результуючий (перегорнутий)  
рядок} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln (St); 
Rez:=''; {Очищення рядка} 
For i:=length(St) downto 1 do 
Rez := Rez+St[i]; {Перегортання рядка} 
If Rez = St  
Then Writeln ('Слово являється паліндромом.') 
Else Writeln ('Слово не являється паліндромом.');  
Readkey; {Затримка зображення на екрані} 
End. 
 

Задача №389(2).
Умова: Визначити, скільки разів у даному тексті зустрічається послідовність символів "абв".
Організовуємо прохід по рядку за допомогою циклу з параметром, причому враховуємо, що необхідно перевірити три послідовно розташованих символи (зверніть увагу на можливість виходу за межі рядка!). Один з методів вибору кількох послідовних символів вже розглядався раніше (і-ий, і+1-ий та і+2-ий елементи), тому розглянемо інший метод, що полягає у використанні функції копіювання Copy. Нагадуємо, що ця функція містить у якості параметрів вихідний рядок, номер початку копіювання (виділення) та кількість вибраних символів, тобто для вибору трьох символів з будь-якого місця рядка St ця функція буде мати вид:
Copy(St,і,3)
.
Порівнюючи виділені (скопійовані) символи з еталоном, нарощуємо лічильник при виконанні поставлених умов.
Програма, що реалізує описаний алгоритм, має наступний вигляд:

Var i:byte; {i - змінна циклу} 
St:string; {St - даний текст} 
Count:byte; {Count - лічильник  
послідовностей} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln (St); 
Count:=0; {Початкове значення лічильника} 
For i:=1 to length(St)-3 do 
If Copy (St,i,3) = 'абв' 
Then count:=count+1; 
Writeln ('Кількість шуканих послідовностей: ',count); 
Readkey; {Затримка зображення на екрані} 
End. 

Задача №394.
Умова: Нехай дано формулу. Визначити коректність формули щодо кількості відкритих та закритих дужок. Вважається, що закриті дужки не стоять перед відкритими. Якщо дужки у формулі відсутні - повідомити про це.
Для визначення коректності формули необхідно підрахувати кількість відкритих та кількість закритих дужок. Якщо ці значення дорівнюють одне одному, баланс дужок виконується, якщо ні - не виконується (дійсно, у правильній формулі кількість відкритих та закритих дужок повинні співпадати). Щоб визначити, чи є в формулі дужки взагалі, достатньо перевірити на нуль кількість одних чи других дужок. Визначимо змінні count_left та count_right, як кількість відповідно лівих (відкритих) та правих (закритих) дужок, тоді програма, що реалізує описаний алгоритм, має наступний вигляд:

 Var i:byte; {i - змінна циклу} 
St:string; {St - даний текст} 
count_left, count_right:byte;  
{count_left - лічильник кількості  
лівих дужок, count_right -  
лічильник кількості правих дужок} 
Begin 
Clrscr; 
Write ('Введіть формулу: '); 
Readln(St); 
Count_left:=0; {Початкове значення лічильника} 
Count_right:=0;  
For i:=1 to length(St) do 
Begin 
If St[i] = '(' 
Then count_left:=count_left+1; 
If St[i] = ')' 
Then count_right:=count_right+1; 
End; 
Writeln ('Кількість лівих дужок: ',count_left); 
Writeln ('Кількість правих дужок: ',count_right); 
If (count_left=0) or (count_right=0) 
Then writeln ('Формула не має дужок.') 
Else 
Begin 
If count_left = count_right 
then Writeln ('Формула коректна.') 
else writeln ('Формула не коректна.'); 
end; 
Readkey; {Затримка зображення на екрані} 
End. 
 

Задача №397.
Умова: Нехай дано текст S та значення символьних змінних x та y. Із тексту вилучити всі символи, що збігаються з x і повторити двічі всі символи, що збігаються з y.
Для розв'язання запропонованої задачі необхідно переглянути кожен символ рядка і, якщо він співпадає з символом x, вилучити його процедурою delete, а якщо збігається із символом y - вставити перед ним такий самий процедурою insert. Програма для реалізації цього алгоритму має наступний вигляд:

Var i:byte; {i - змінна циклу} 
S:string; {S - даний текст} 
x,y:char; {x,y - шукані символи} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln (S); 
Write ('Введіть шукані символи: '); 
Readln (x,y); 
For i:=1 to length(S) do 
Begin 
If S[i] = x 
Then delete(S,i,1); 
If S[i] = ')' 
Then insert(y,S,i); 
End; 
Writeln ('Результуючий рядок після зміни: ',S); 
Readkey; {Затримка зображення на екрані} 
End. 
 

Задача №401.
Умова: Розробити програму-шифрувальник тексту, що замінює кожну його літеру наступною по порядку в абетці. Останню літеру абетки необхідно замінити першою.
В даній задачі необхідно, по-перше, перевірити, чи є черговий символ рядка буквою. Відомо, що всі букви латиниці розташовані в таблиці ASCII-кодів двома групами великих та малих літер, а літери кирилиці - двома нерівномірними групами від 'А' до 'п' та від 'р' до 'я':
'A'.. 'Z' - коди 65 .. 90;
'a'..'z' - коди 97 .. 122;
'А'..'п' - коди 128 .. 175;
'р'..'ї' - коди 224 .. 245.
Якщо черговий символ рядка - буква, необхідно збільшити її код на 1, а потім перетворити отриманий код в букву. Для визначення коду за символом використовується процедура ord, а для визначення символу за ASCII-кодом - процедура char. Для останніх літер необхідно написати незалежні команди розгалуження для заміни їх на перші літери абетки, причому для символів латиниці можна скористатися однією формулою chr(ord(S[i])-25), тому що, кількість великих та малих літер в абетці однакові і відстань від першої літери до останньої дорівнює 25.
Програма для реалізації описаного алгоритму має наступний вигляд:

Var i:byte; {i - змінна циклу} 
S:string; {S - даний текст} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln (S); 
For i:=1 to length(S) do 
Begin 
If (S[i]>=65) and (S[i]<90) or 
(S[i]>=97) and (S[i]<122) or 
(S[i]>=128) and (S[i]<159) or 
(S[i]>=160) and (S[i]<=175) or 
(S[i]>=224) and (S[i]<245) or 
Then S[i]:=chr(ord(S[i]+1); 
If (S[i] = 'Z') or (S[i] = 'z') 
Then S[i]:=chr(ord(S[i])-25); 
If (S[i] = 'Я') 
Then S[і]:='А'; 
If (S[i] = 'я') 
Then S[і]:='а'; 
End; 
Writeln ('Результуючий рядок після зміни: ',S); 
Readkey; {Затримка зображення на екрані} 
End. 

Задача №406(3).
Умова: Дано деякий текст. Групи символів, які розділені пробілами (одним або кількома) та не містять всередині себе пробілів, називатимемо словами. Вважатимемо, що текст завжди починається зі слова. Визначити кількість слів, у яких перша та остання літера однакові.
При виконанні розв'язку цієї задачі, очевидно, що початок першого слова буде співпадати з першою літерою рядка (дивись умову), а кінець слова можна визначити, знайшовши перший проміжок. Скопіювавши це слово в додатковий рядок, ми отримаємо нескладну задачу порівняти його перший та останній символи. Якщо ці символи співпадають, слово підраховується, і процес продовжується для наступного слова.
Щоб задачу пошуку чергового слова зробити ідентичною для всіх слів, можна вважати, що початком слова є послідовність з проміжку та непроміжку, а відповідно кінцем слова є послідовність з непроміжку та проміжку (цей метод зручний ще тим, що враховує те, що між словами може бути не один проміжок - всі зайві проміжки пропускаються). Виділятися з цього буде перше та останні слова, тому що на початку рядка та в його кінці користувач може не поставити проміжок і ці слова не буде знайденим. Щоб узагальнити задачу пропонуємо один зі штучних методів: дописати на початку та в кінці рядка проміжки . Тоді, програма для реалізації описаного алгоритму буде мати наступний вигляд:

Var i:byte; {i - змінна циклу} 
S,Slovo:string; {S - даний текст, Slovo -  
вирізане з тексту слово} 
count:byte; {count - лічильник шуканих  
слів} 
Begin 
Clrscr; 
Write ('Введіть текст: '); 
Readln (S); 
S:=' '+S+' '; {Дописування проміжку перед  
першим словом та після  
останнього} 
Count:=0; {Початкове значення лічильника} 
i:=1; {Початок перегляду рядка} 
while i<=length(S)-1 do 
Begin 
If (S[i]=' ') and (S[i+1]<>' ') 
Then  
Begin 
Slovo:=''; {Очищення рядка для  
зберігання чергового слова} 
While (S[i+1]<>' ') do 
Begin 
Slovo:=Slovo+S[i+1]; 
i:=i+1; 
End; 
If Slovo[1] = Slovo[length(Slovo)]  
Then count:=count+1; 
End; 
i:=i+1; 
End; 
Writeln ('Кількість шуканих слів: ',count); 
Readkey; {Затримка зображення на екрані} 
End.  

Домашнє завдання:
Повторити сторінки 120 - 123 запропонованого підручника;
Задачі №384(1), №388, №389(1,3,4), №390, №396, №399, №406(1,2,4).