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

Лабораторна робота № 4 Робота з рядками|

Мета. Отримати тримати практичні навички навички роботи з рядками на С++.

Короткі теоретичні відомості

У С/С++ рядок символів розглядається|розглядується| як звичайний|звичний| масив символів, в якому останнім слідує|прямує| символ закінчення рядка ‘\0’ . При цьому довжина масиву визначається на одиницю більше довжини реального рядка.

Функції обробки рядків описані|перебувають| в модулі string.h. (основні з|із| них див. в додатку А)|посібнику|.

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

Наприклад. Необхідно ввести|запровадити| послідовність рядків довільної довжини і вивести їх на екран.

#include<iostream.h>

#include<string.h>

#include<conio.h>//містить прототипи функцій clrscr() і getch()

#include<process.h>//містить прототип функції exit()

void main()

{ clrscr();

char* str_temp=new char[255]; /* визначаємо буферний рядок, який може містити максимальну кількість символів */

char** m_str;

int i,j,n;

cout<<"\n Введіть кількість рядків ";

cin>>n;

m_str=new char*[n]; /* розподіляємо пам'ять під зберігання адреси кожного

рядка, що вводиться|запроваджується|. Якщо оператор new повертає як адресу NULL, то повідомляємо користувача про помилку і припиняємо роботу функції main() */

if(!m_str){ cerr<<"\n Помилка при розподілі пам’яті";

exit(1);}

cin.ignore(); /* функція-член класу cin, яка ігнорує за умовчанням код символу “Enter”, який було натиснуто при вводі кількості рядків. Функція має два параметри (int, char) – кількість символів ігнорування і символ, який стоїть в кінці|у кінці,наприкінці| цієї послідовності */

for(i=0;i<n;i++)

{ cout<<"\n Введіть "<<i+1<<"-ий рядок ";

cin.getline(str_temp,255); /* функція-член класу cin, яка дозволяє занести

символи з вхідного потоку в змінну str_temp. Другий параметр визначає максимальну довжину рядка.*/

m_str[i]=new char[strlen(str_temp)+1]; /* розподіляємо пам'ять під зберігання рядка, що вводиться|запроваджується| за допомогою буферного рядка. Оскільки функція strlen() визначає довжину рядка без урахування символу нуля, то додаємо|добавляємо| 1 до реального значення довжини рядка, резервуючи місце для символу завершення рядка */

if(!m_str[i]){ cerr<<"\n Помилка при розподілі пам’яті ";

exit(1);}

strcpy(m_str[i],str_temp);}

delete[] str_temp; // звільняємо пам’ять, яку було зайнято буферним рядком

cout<<"\n Масив рядків, який введено\n";

for(i=0;i<n;i++)

{ cout<<m_str[i]<<endl; //виводимо рядок на екран

delete[] m_str[i];} /* звільняємо пам’ять, яка була зайнята під ряжок, який виведено на екран */.

delete[] m_str; /*звільняємо пам’ять, яку було зарезервовано під зберігання масиву адрес рядків */

getch();

}

Завдання до лабораторної роботи №4

  1. Вивчити правила створення та обробки рядків символів на прикладі програм, що розглянуті в п.п. «Короткі теоретичні відомості» та «Приклад виконання лабораторної роботи №4». Перевірити роботу наведених програм.

  2. Пояснити основні принципи розподілу пам’яті під символьні рядки. Визначити відмінність символьного рядка від звичайного масиву.

  3. |задачі|Написати програму, що дозволяє вирішити поставлену в індивідуальному завданні задачу з використанням символьних рядків.

Приклад виконання лабораторної роботи №4

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

Для вирішення цієї задачі використаємо стандартні функції модулю string.h:

strtok((char* p,char separator) - при першому виклику відділяє з рядка, адресу якого містить покажчик p, підрядок, який обмежено справа символом separator. Для подальшого відокремлення наступних слів в тому самому рядку необхідно перший параметр вказувати нульовим (NULL);

strcpy(char* s1,char* s2) – дозволяє скопіювати значення рядка s2 в рядок s1;

strcat(char* s1,char*s2) – дозволяє приєднати до рядка s1 рядок s2. При цьому символ закінчення рядка s1 - “\0” ігнорується і замінюється початковим символом рядка s2;

strstr(char* s1,char* s2) – перевіряє входження рядка s2 в рядок s1. Якщо таке входження є, функція повертає адресу того символу рядка, з якого починається входження, в протилежному випадку повертає нульове значення.

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

  1. Приклад визначення рядків:

char inp[80], //вихідний рядок

rez[80]=" ", //рядок - результат

p1[80]; //допоміжний рядок

  1. Приклад вводу значень вихідного рядка:

cout<<"\nInput string\n";

cin.getline(inp,80);

  1. Приклад відокремлення слів в заданому рядку

char *p; /*за допомогою покажчика p здійснюватиметься перехід по елементах рядка */

int k=1; /*прапорець, який дозволить відрізнити перший та подальші виклики функції strtok */

do

{p = strtok((k?inp:NULL), " ");

/*відділити слово вихідного рядка inp, його адресу занести в покажчик p. Першим параметром функції strtok стоїть умовний оператор ?:. Оскільки спочатку k=1, результатом дії умовного оператора буде inp, що відповідатиме першому виклику функції, */

k=0;

/*після першого виклику k змінює значення на 0, результатом дії умовного оператора в якості параметра функції буде NULL, що відповідатиме всім наступним викликам цієї функції. Таким чином здійснюватиметься перехід по всьому рядку inp */

if (p) cout<<endl<<p;//вивести на екран відокремлене слово, яке саме по

// собі є рядком

}while(p); /*виконувати, поки покажчик не нульовий, тобто поки рядок містить хоча б одне слово */

  1. Приклад перевірки наявності слова в рядку результату. Поставлену задачу можна вирішувати декількома способами, але слід враховувати, що виходячи з умов послідовності однакових символів, які мають різну довжину також вважаються і різними словами. Наприклад, слова «ААА» і «АА» є різними, оскільки мають різну довжину. Щоб відрізнити такі слова можна визначати їх довжину, а можна з обох сторін додати сигнальні символи, наприклад пропуски.

if (p) //якщо покажчик pне нульовий

{ cout<<endl<<p;

strcpy(p1," ");//починаємо формувати слово, обмежене пропусками

strcat(p1,p); /*додаємо до допоміжного рядка відокремлене функцією

strtok слово з початковою адресою p*/

strcat(p1," ");//додаємо на при кінці слова p1 пропуск

if(!strstr(rez,p1)) //якщо слово p1не входить в рядок результату rez

{strcat(rez,p); //додати до рядка результату відокремлене слово з

//адресою p

strcat(rez," ");//додати в кінці рядка результату пропуск для

//відокремлення доданих слів

}

}

Необхідність додавання пропусків на етапі перевірки наявності відокремленого слова в рядку результату викликана дією функції strstr. Наприклад, задано рядок «чсм чс см». Першим в рядок результату буде занесено слово «чсм». В заданому рядку всі слова різні і всі повинні бути занесені в результат, але слово «чс» міститься в слові «чсм». В цьому випадку функція поверне ненульовий результат і слово «чс» не буде враховано, так само, як не буде враховано і слово «см». Якщо для перевірки входження всі слова рядка обмежити пропусками, то матимемо: « чсм », « чс », « см ».Це вже зовсім різні послідовності символів, і жодна з них цілком не містить іншої. Саме з цією метою в наведеному фрагменті програми використано допоміжний рядок p1

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

#include <string.h>

#include <iostream.h>

#include <conio.h>

void main()

{ char inp[80],rez[80]=" ",p1[80];

char *p;

cout<<"\nInput string\n";

cin.getline(inp,80);

int k=1;

do

{p = strtok((k?inp:NULL), " ");

k=0;

if (p)

{ cout<<endl<<p;

strcpy(p1," ");

strcat(p1,p);

strcat(p1," ");

if(!strstr(rez,p1)) {strcat(rez,p);

strcat(rez," ");}

}

}while(p);

cout<<endl<<"rez ="<<rez;

getch();

}

Зміст|вміст,утримання| звіту до лабораторної роботи №4

  1. Титульний лист|аркуш|: назва дисципліни; номер і найменування роботи; прізвище, ім'я, по батькові студента; дата виконання.

  2. Постановка завдання|задачі|. Слід зазначити, який спосіб організації даних(статичний або динамічний) обрано та чому.

  3. Визначення основних змінних та функцій з|із| коментарями.

  4. Реалізація функцій.

  5. Лістинг основної програми, в якому повинно бути вказано, в якому місці і яка функція викликається|спричиняються|.

Варіанти завдань до лабораторної роботи №4

  1. Видалити|знищити,віддалити| зайві пропуски|прогалини| у введеному|запровадженому| рядку символів.

  2. Порахувати|полічити| частоту появи букв|літер| в рядку, якщо вважати|лічити| рівними букви|літери| у верхньому і нижньому регістрах|реєстрі|.

  3. У рядку слів всі слова, що складаються з чотирьох букв|літер|, видалити|знищити,віддалити|, а слова, що складаються з п'яти букв|літер|, замінити словом “комп’ютер”.

  4. Ввести|запровадити| рядок символів і перетворити по можливості в число типу int або float за наступним|слідуючим| правилом: рядок “123.45” перетвориться в число 123.45; рядок 123 - в число 123.

  5. Задано масив рядків, що складаються з трьох символів. Відсортувати рядки по першій букві|літері| вубутному порядку|ладі|.

  6. Вводити|запроваджувати| масив рядків, довжина яких не більше певного числа. Знайти рядок найменшої довжини і вирівняти всі рядки до довжини найменшого рядка.

  7. Вводиться|запроваджується| рядок символів. Символи, які оточені пропусками|прогалинами|, називаються словами. Необхідно знайти в рядку слова, які починаються з однієї і тієї ж букви|літери|, і поміняти їх місцями.

  8. Вводиться|запроваджується| рядок слів (слово - рядок символів, які оточені пропусками|прогалинами|). Відсортувати слова по першій букві|літері|.

  9. Вводиться|запроваджується| рядок символів, в якому можуть бути символи верхнього і нижнього регістрів|реєстру|. Необхідно символи верхнього регістра|реєстру| замінити символом " * ".

  10. Вводиться|запроваджується| масив рядків символів. Необхідно знайти рядок найбільшої довжини і збільшити всю решту рядків в масиві до довжини найбільшого рядка, використовуючи символ " ! ".

  11. У рядку слів з|із| букв|літер| латинського алфавіту знайти слова, в яких немає букв|літер|, що повторюються.

  12. У рядку слів з|із| букв|літер| латинського алфавіту знайти слова, в яких перша буква|літера| слова входить ще хоч би один раз.

  13. У рядку слів з|із| букв|літер| латинського алфавіту знайти найкоротше симетричне слово.

  14. Вводиться|запроваджується| рядок символів, серед яких є хоч би один символ " : ". Необхідно записати в зворотному порядку|ладі| символи, які зустрінуться до першого " : " і підрахувати|підсумувати| кількість символів між символами " :", якщо таких декілька.

  15. Вводиться|запроваджується| рядок слів (слово - рядок символів, які оточені пропусками|прогалинами|). Необхідно знайти слова, що складаються тільки|лише| з букв|літер| і лише з|із| цифр.

  16. Вводиться|запроваджується| масив рядків довільної довжини (не більше заданого числа). Необхідно відсортувати слова в неубутному порядку|ладі| по останньому символу в рядках і по довжині рядків.

  17. Використовуючи послідовність рядків (кожен рядок – деяке число в двійковій системі числення|обчислення|), скласти рядок з|із| чисел десяткової системи числення|обчислення| (і-е число відповідає і-й рядку початкової|вихідної| послідовності).

  18. Написати рекурсивну функцію визначення довжини рядка.

  19. Заданий словник слів. Необхідно визначити, чи можна у введеній|запровадженій| послідовності символів виділити слова із|із| словника.

  20. У вигляді рядка символів задано арифметичний вираз|вираження|. Обчислити|обчисляти,вичислити| його, задавши значення відповідних змінних.

  21. Написати функції додавання|добавки| підрядка і видалення|віддалення| підрядка в будь-якому вказаному місці заданого рядка.

  22. Задано два рядки слів. Перетворити їх в один за принципом: Задано: рядок1слово1 слово2 слово3 .. рядок2слово1 слово2 слово3 .. Одержати|отримати|: ряд1слово1 ряд2слово1 ряд1слово2 ряд2слово2 ….

  23. Заданий словник-перекладач у вигляді двовимірного масиву рядків. Написати програму, що дозволяє одержати|отримати| переклад|переведення,переказ| введеного|запровадженого| рядка.

  24. Скласти програму, яка підраховує|підсумовує| частоту повторення двохбуквених поєднань в заданому тексті. Вивести тільки|лише| ті з|із| них, частота повторення яких не менше 10%.

  25. Заданий масив рядків довільної довжини. Визначити, чи є|з'являється,являється| симетричною матриця символів, побудованих|споруджених| з|із| рядків.

  26. Написати програму “демовірус|”: вводиться|запроваджується| рядок символів, починаючи|розпочинаючи,зачинаючи| з|із| середини рядка букви|літери| починають|розпочинають,зачинають| “падати вниз” - спочатку одна, потім дві і т.д. При цьому рядок, поступово стискаючись|стискуючись|, в кінці|у кінці,наприкінці| зовсім зникає.

  27. Заданий масив слів – словник. Користувач вводить|запроваджує| слово пошуку по одній букві|літері|. Після|потім| кожної введеної|запровадженої| букви|літери| слова на екрані відображається|відображується| список всіх можливих слів продовжень із|із| словника, або з'являється|появляється| повідомлення|сполучення| про відсутність даного слова.

  28. Заданий рядок слів довільної довжини. Сформувати динамічний масив рядків слів певної довжини. Упорядкувати одержаний|отриманий| масив.

  29. Заданий масив рядків довільної довжини. Відформатувати даний масив рядків по ширині поля і посторінково.

  30. Заданий масив рядків і словник. Визначити входження слів словника в заданий масив як по вертикалі, так і по горизонталі.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]