C++. Масиви. Частина 4. Приклади розв’язування задач на рядки символів




Масиви. Частина 4. Приклади розв’язування задач на рядки символів

У даній темі розв’язуються деякі задачі з використанням рядків символів. При розв’язку цих задач використовуються деякі стандартні функції з бібліотеки “string.h“.

Тема продовжує вивчення тем: одновимірні масиви та багатовимірні масиви.


Зміст


Пошук на інших ресурсах:

1. Задачі на пошук символу в рядку. Приклади

Приклад 1. Задано рядок символів. Визначити, чи є заданий символ c в цьому рядку символів.

// пошук символу в рядку
char S[50]; // рядок символів
char c; // шуканий символ
int i;
bool f_is; // f_is=true - символ є в рядку, інакше f_is=false

// ввід рядка S
// ...
// ввід символу c
// ...

for (i=0; i<strlen(S); i++)
    if (S[i]==c)
    {
        f_is = true; // символ c є в рядку S
        break;
    }

if (f_is)
    label1->Text = "Символ " + c.ToString() + " є в рядку";
else
    label1->Text = "Символу " + c.ToString() + "немає в рядку";

У даному прикладі для визначення довжини рядка S використовується функція

strlen(S)

Ця функція повертає кількість символів у рядку без врахування останнього символу ‘\0’. Щоб використовувати цю функцію в Visual C++ потрібно на початку файлу перед задаванням простору імен підключити одну з бібліотек <string.h> або <cstring>. Для цього потрібно набрати один з рядків:

#include <string.h>

або

#include <cstring> 

Приклад 2. Нехай задано деякий текст. Обчислити, скільки разів повторюється наперед заданий символ a.

// знаходження кількості входжень символу в рядку
char S[50]; // рядок символів
char a; // заданий символ
int i;
int k; // результат - кількість входжень символу a в рядку S

// ввід рядка S
// ...
// ввід символу a
// ...

k = 0; // на початку обнулити лічильник k
for (i=0; i<strlen(S); i++)
    if (S[i]==a)
        k++; // збільшити лічильник на 1

Приклад 3. У даному тексті порахувати кількість символів ‘+’ та .

// підрахунок кількості символів у рядку
char str[50]; // заданий текст
int i;
int n_p; // результат - кількість символів '+'
int n_m; // результат - кількість символів '-'

// ввід масиву str
// ...

n_p = 0;
n_m = 0;
for (i=0; i<strlen(str); i++)
{
    if (str[i] == '+')
       n_p++;
    if (str[i] == '-')
       n_m++;
}

2. Задачі на заміну символів. Приклади

Приклад 1. У заданому тексті замінити всі символи ‘+’ на ‘-‘.

// заміна символів
char str[50]; // заданий текст
int i;

// ввід тексту
// ...

for (i=0; i<strlen(str); i++)
    if (str[i] == '+')
        str[i] = '-';


Приклад 2. Задано декілька рядків тексту (двовимірний масив символів). Замінити всі символи ‘+’ на ‘-‘.

// заміна символів в масиві рядків
char str[5][50]; // заданий масив, що містить 5 рядків
int i, j;

// ввід масиву з 5 рядків
// ...

for (i=0; i<5; i++)
    for (j=0; j<strlen(str[i]); j++)
        if (str[i][j] == '+')
            str[i][j] = '-';

Приклад 3. У заданому тексті замінити всі символи ‘+’ на ‘+++’.

Дана задача легко вирішується з допомогою введення допоміжного масиву у текст програми.

// заміна символів '+' на '+++'
char str[50]; // заданий текст
int i, j;
char str2[150]; // допоміжний масив

// ввід масиву str
// ...

j = 0; // поточна позиція в масиві str2
for (i=0; i<strlen(str); i++)
    if (str[i] == '+')
    {
        str2[j++] = '+';
        str2[j++] = '+';
        str2[j++] = '+';
    }
    else
    {
        str2[j] = str[i];
        j++;
    }

// додати символ кінця рядка
str2[j] = '\0';
strcpy(str, str2); // скопіювати str2 в str 

Приклад 4. У заданому тексті замінити послідовність символів ‘…’ на ‘ . ‘.

// заміна символів '...' на '.'
char str[50]; // заданий текст
int i, j;
char str2[50]; // допоміжний масив
int d;

// ввід масиву str
// ...

j = 0; // поточна позиція в масиві str2
d = strlen(str); // довжина рядка str

for (i=0; i<d; i++)
    if (i<d-2)
    {
        if ((str[i]=='.')&&(str[i+1]=='.')&&(str[i+2]=='.'))
        {
            str2[j++] = '.';
            i+=2;
        }
        else
        {
            str2[j++] = str[i];
        }
    }
    else
    {
        str2[j++] = str[i];
    }

// додати символ кінця рядка
str2[j] = '\0';
strcpy(str, str2); // скопіювати допоміжний масив у вихідний

Так само, як і в попередньому прикладі вводиться допоміжний масив. У вихідному масиві відбувається перевірка на послідовність символів ‘…’

if ((str[i]=='.')&&(str[i+1]=='.')&&(str[i+2]=='.'))

Якщо така послідовність знайдена, то в допоміжному масиві додається ‘ .

str2[j++] = '.';
i+=2;

В іншому випадку, символ з вихідного масиву копіюється у допоміжний.

str2[j++] = str[i];

У лістингу використовується функція strcpy() з бібліотеки <string.h> (або cstring), яка копіює один рядок в інший.

3. Задачі на визначення позиції заданого символу. Приклади

Приклад 1. Задано деякий рядок символів. У заданому тексті визначити позицію першої крапки ‘ . ‘. Вважати, що перший символ в рядку має позицію 1.

// пошук першого входження символу в тексті
char str[50]; // заданий текст
int i;
int pos; // шукане значення - позиція

// ввід масиву str
// ...

pos = -1;

for (i=0; i<strlen(str); i++)
    if (str[i]=='.')
    {
        pos = i+1; // запам'ятати позицію
        break; // вихід з циклу, подальше виконання циклу не має сенсу
    }

if (pos == -1)
    label2->Text = "Символ відсутній в тексті.";
else
    label2->Text = pos.ToString();

Приклад 2. Задано деякий рядок символів. Визначити позиції останньої крапки ‘ . ‘ в тексті.

// пошук останнього входження символу в тексті
 char str[50]; // заданий текст
 int i;
 int pos; // шукане значення - позиція

// ввід масиву str
// ...

pos = -1;

for (i=strlen(str)-1; i>=0; i--) // перегляд рядка з кінця до початку
    if (str[i]=='.')
    {
        pos = i+1; // запам'ятати позицію
        break; // вихід з циклу, подальше виконання циклу не має сенсу
    }

if (pos == -1)
    label2->Text = "Символ відсутній в тексті.";
else
    label2->Text = pos.ToString();

4. Задачі на перетворення тексту. Приклади

Приклад 1. Задано деякий рядок символів. Створити новий рядок, який утворено із даного читанням з кінця до початку.

// обернення рядка
char str[50];  // заданий рядок
char str2[50]; // результуючий рядок
int i;
int d;

// ввід масиву str
// ...

d = strlen(str);

for (i=0; i<d; i++)
    str2[d-i-1] = str[i];

// додати символ кінця рядка
str2[d] = '\0';

Приклад 2. Задано слово. Перевірити, чи читається це слово зліва направо і навпаки.

// перевірка рядка
char str[50]; // заданий рядок
int i;
int d;
bool f_yes; // результуюча змінна

// ввід масиву str
// ...

d = strlen(str);
f_yes = true;
for (i=0; i<d/2; i++) // перегляд рядка з кінця до початку
    if (str[i] != str[d-i-1])
        f_yes = false;

if (f_yes)
    label1->Text = "Рядок читається зліва направо і навпаки";
else
    label1->Text = "Рядок не читається зліва направо і навпаки";

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

// перевірка на оберненість двох слів
char str1[50]; // рядок 1
char str2[50]; // рядок 2
int i;
int d1, d2;
bool f_yes; // результуюча змінна

// ввід масивів str1, str2
// ...

d1 = strlen(str1);
d2 = strlen(str2);

f_yes = true;

if (d1 == d2) // перевірка довжин рядків на співпадіння
{
    for (i=0; i<d1; i++)
        if (str1[i] != str2[d1-i-1])
            f_yes = false;
}
else
    f_yes = false;

if (f_yes)
    label1->Text = "Слова є оберненими один до одного";
else
    label1->Text = "Слова не є оберненими один до одного";

5. Задачі на підрахунок кількості символів в тексті. Приклади

Приклад 1. Задано рядок символів. Підрахувати кількість символів ‘+’ у цьому рядку.

// підрахунок кількості символів '+' у рядку
char str[50];
int i;
int k; // результат - кількість символів

// ввід рядка str
// ...

k = 0; // онулити лічильник

for (i=0; i<strlen(str); i++)
    if (str[i] == '+')
        k++;

// вивід результату
label1->Text = k.ToString();

Приклад 2. Задано декілька рядків символів. Підрахувати кількість символів ‘ – ‘ у цих рядках.

// підрахунок кількості символів '-' у масиві з 6 рядків
char s[6][50];
int i, j;
int k; // результат - кількість символів

// ввід рядків s
// ...
k = 0; // онулити лічильник

// обчислення k
for (i=0; i<6; i++)
    for (j=0; j<strlen(s[i]); j++)
        if (s[i][j] == '-')
            k++;

// вивід результату
label1->Text = k.ToString();

Приклад 3. Задано рядок символів. Підрахувати кількість слів у цьому рядку. Вважати, що слова розділяються одним з символів ‘ ‘ (пробіл), ‘ , ‘ (кома), ‘ . ‘ (крапка).

// підрахунок кількості слів у рядку
char s[50]; // рядок символів
int i;
int k; // результат - кількість слів
bool f; // допоміжна змінна - визначає кінець попереднього слова

// ввід рядку s
// ...

k = 0; // онулити лічильник
f = true;

// обчислення k
for (i=0; i<strlen(s); i++)
    if ((s[i] == ' ')||(s[i]==',')||(s[i]=='.'))
    {
        f = true; // кінець слова
    }
    else
    {
        if (f)
        {
            // початок нового слова
            k++;
            f = false;
        }
    }

// вивід результату
label1->Text = k.ToString();

У вищенаведеному прикладі з допомогою допоміжної змінної f визначається кінець попереднього слова. Якщо

f = true

тоді був кінець попереднього слова. Інакше, починається нове слово і лічильник k збільшується на 1.

Приклад 4. Задано декілька рядків символів (двовимірний масив символів). Підрахувати кількість слів, що починаються з літер ‘a’ або ‘A’. Вважати, що слово закінчується на один з символів ‘ ‘ (пробіл), ‘ . ‘ (крапка) або ‘ , ‘ (кома).

// підрахунок кількості слів у масиві рядків
char s[5][50]; // масив рядків символів
int i, j;
int k; // результат - кількість слів
bool f; // допоміжна змінна - визначає кінець попереднього слова

// ввід масиву рядків s
// ...

k = 0; // онулити лічильник

// обчислення k
for (i=0; i<5; i++) // перебір рядків
{
    f = true;
    for (j=0; j<strlen(s[i]); j++)
        if ((s[i][j] == ' ')||(s[i][j]==',')||(s[i][j]=='.'))
    {
        f = true; // кінець слова
    }
    else
    {
        if (f)
        {
            // початок нового слова
            if ((s[i][j]=='a')||(s[i][j]=='A'))
                k++;
            f = false;
        }
    }
}

// вивід результату
label1->Text = k.ToString();

6. Сортування рядків символів методом вставки. Приклад

Приклад. Задано декілька рядків символів. Посортувати ці рядки в алфавітному порядку.

// сортування масиву рядків методом вставки
char s[5][50]; // масив рядків символів
int i, j;
char ts[50]; // допоміжний рядок

// ввід масиву рядків s
// ...

for (i=0; i<4; i++)
    for (j=i; j>=0; j--)
        if (strcmp(s[j],s[j+1])>0)
        {
            // обміняти рядки місцями
            strcpy(ts, s[j]);
            strcpy(s[j], s[j+1]);
            strcpy(s[j+1], ts);
        }

У вищенаведеному лістингу для порівняння рядків у лексикографічному порядку використовується функція strcmp() з бібліотеки <string.h> (cstring). Функція має загальну форму:

int strcmp(string1, string2);

де string1, string2 – рядки, що порівнюються.

Функція повертає число:

  • >0, якщо string1 слідує після string2 в лексикографічному порядку;
  • =0, якщо рядки однакові;
  • <0, якщо string1 слідує перед string2 в лексикографічному порядку.


Зв’язані теми