Приклад виконання лабораторної роботи №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]; //допоміжний рядок

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

cout<<"\nInput string\n";

cin.getline(inp,80);

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

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); /*виконувати, поки покажчик не нульовий, тобто поки рядок містить хоча б одне слово */

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

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

 

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

#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();

}