Загрузка данных


ЛАБОРАТОРНАЯ РАБОТА №10
Обработка строк
Вариант №6 (стр. 23)

================================================================================
ЗАДАНИЕ 1
================================================================================

Текст задания:
Вводится строка произвольного текста. Вывести на экран все знаки препинания
из этой строки. Если таких символов нет, вывести -1.

Назначение переменных:
- punct (string) – строка, содержащая все знаки препинания (точка, запятая,
  восклицательный знак, вопросительный знак, двоеточие, точка с запятой)
- str (string) – исходная строка, введённая пользователем
- strTemp (string) – строка для накопления найденных знаков препинания

Описание кода:
Программа запрашивает у пользователя строку. Затем проходит по всем символам
строки с конца к началу. Для каждого символа проверяет, является ли он знаком
препинания (сравнивает со строкой punct). Если символ является знаком
препинания, он добавляется в начало строки strTemp. После завершения цикла,
если длина строки strTemp меньше или равна 1, программа выводит -1.
В противном случае выводит найденные знаки препинания.

Текст программы:
--------------------------------------------------------------------------------
#include <iostream>
using namespace std;

int main()
{
    string punct = ".,!?:;";
    string str = "";
    string strTemp = "";
    
    cout<<"Введите строку:"<<"\n";
    getline(cin, str); 
    
    for (int i = str.length(); i > 0; i--)
    {
        for (int j = 0; j <= punct.length(); j++)
        {
            if (punct[j] == str[i]) 
            {
                strTemp = str[i] + strTemp;
            }
        }
    }
    
    if  (strTemp.length() <= 1)
    {
        cout<<"-1"<<"\n";
    }
    else
    {
        cout<<"Знаки препинания:"<<strTemp<<"\n";
    }
    
    return 0;
}

================================================================================
ЗАДАНИЕ 2
================================================================================

Текст задания:
Вводится строка произвольного текста, затем вводится произвольный символ.
Удалить все вхождения этого символа из строки. Вывести преобразованную
таким образом строку.

ПРИМЕЧАНИЕ: В предоставленном коде удаляются пробелы, а не произвольный символ.
Для соответствия заданию нужно заменить условие str[i] != ' ' на
str[i] != ch и добавить ввод символа. Ниже приведён исправленный вариант.

Назначение переменных (исправленный вариант):
- str (string) – исходная строка, введённая пользователем
- strTemp (string) – строка для накопления символов, не равных удаляемому
- ch (char) – символ, который нужно удалить

Описание кода (исправленный вариант):
Программа запрашивает строку и символ для удаления. Затем проходит по всем
символам исходной строки. Если символ не равен удаляемому, он добавляется
в строку strTemp. После завершения цикла выводится полученная строка.

Текст программы (исправленный):
--------------------------------------------------------------------------------
#include <iostream>
using namespace std;

int main()
{
    string str = "";
    string strTemp = "";
    char ch;
    
    cout<<"Введите строку:"<<"\n";
    getline(cin, str);
    cout<<"Введите символ для удаления:"<<"\n";
    cin>>ch;
    
    for (int i = 0; i < str.length(); i = i + 1)
    {
        if (str[i] != ch) 
        {
            strTemp = strTemp + str[i];
        }
    }
    
    cout<<"Результат:"<<strTemp<<"\n";
    
    return 0;
}

Текст программы (оригинальный, удаляет пробелы):
--------------------------------------------------------------------------------
// #include <iostream>
// using namespace std;
// 
// int main()
// {
//     string str = "";
//     string strTemp = "";
//     
//     cout<<"Введите строку:"<<"\n";
//     getline(cin, str); 
//     
//     for (int i = str.length(); i >= 0; i--)
//     {
//         if (str[i] != ' ') 
//         {
//             strTemp = str[i] + strTemp;
//         }
//     }
//     
//     cout<<"Строка без пробелов:"<<strTemp<<"\n";
//     
//     return 0;
// }

================================================================================
ЗАДАНИЕ 3
================================================================================

Текст задания:
Вводится строка символов. Удалить все пробелы в начале и конце строки,
если они там есть. Предусмотреть вариант, когда в начале и (или) конце
строки пробелы отсутствуют.

ПРИМЕЧАНИЕ: В предоставленном коде подсчитывается количество букв в последнем
слове, что не соответствует заданию. Для соответствия заданию нужно
реализовать удаление пробелов по краям. Ниже приведён правильный вариант.

Назначение переменных (правильный вариант):
- str (string) – исходная строка
- start (int) – индекс первого непробельного символа
- end (int) – индекс последнего непробельного символа

Описание кода (правильный вариант):
Программа запрашивает строку. Сначала пропускаются все пробелы в начале
строки (увеличивается start). Затем пропускаются все пробелы в конце строки
(уменьшается end). Если start меньше или равен end, строка обрезается с помощью
substr. Если вся строка состояла из пробелов, результатом будет пустая строка.

Текст программы (правильный вариант):
--------------------------------------------------------------------------------
#include <iostream>
#include <string>
using namespace std;

int main()
{
    string str;
    
    cout<<"Введите строку:"<<"\n";
    getline(cin, str);
    
    int start = 0;
    int end = str.length() - 1;
    
    while (start < str.length() && str[start] == ' ')
    {
        start = start + 1;
    }
    
    while (end >= 0 && str[end] == ' ')
    {
        end = end - 1;
    }
    
    if (start <= end)
    {
        str = str.substr(start, end - start + 1);
    }
    else
    {
        str = "";
    }
    
    cout<<"Результат: "<<str<<"\n";
    
    return 0;
}

Текст программы (оригинальный, считает буквы в последнем слове):
--------------------------------------------------------------------------------
// #include <iostream>
// using namespace std;
// 
// int main()
// {
//     int count = 0;
//     string str = "";
//     
//     cout<<"Введите строку:"<<"\n";
//     getline(cin, str); 
//     int number = str.length() - 1;
// 
//     while (number >= 0 && str[number] == ' ') 
//     {
//         number--;
//     }
// 
//     while (number >= 0 && str[number] != ' ') 
//     {
//         if (isalpha(str[number]))
//         {   
//             count++;
//         }
//         number--;
//     }
//     
//     cout<<"В последнем слове "<<count<<" букв\n";
//     
//     return 0;
// }

================================================================================
ЗАДАНИЕ 4
================================================================================

Текст задания:
Вводится строка символов, которые разделены на слова. Пробелы являются
разделителями между словами, причём слова могут разделяться более чем одним
пробелом, в начале и конце строки пробелы также допускаются.
Вывести на экран все слова, состоящие из пяти букв.

Назначение переменных:
- str (string) – исходная строка
- tempstr (string) – временная строка для накопления текущего слова
- count (int) – счётчик (в данном коде не используется)

Описание кода:
Программа запрашивает строку. Затем проходит по всем символам строки.
Если символ не является пробелом и является буквой, он добавляется в
временную строку tempstr. Если встречается пробел или конец строки,
и длина tempstr больше 0, программа выводит tempstr (все слова подряд).
Затем tempstr очищается.

ПРИМЕЧАНИЕ: Данный код выводит все слова, а не только из пяти букв.
Для соответствия заданию нужно добавить проверку tempstr.length() == 5.

Текст программы (оригинальный, выводит все слова):
--------------------------------------------------------------------------------
#include <iostream>
using namespace std;

int main()
{
    int count = 0;
    string str = "";
    string tempstr = "";
    
    cout<<"Введите строку:"<<"\n";
    getline(cin, str); 
    int number = 0;
    
    for (int i = 0; i <= str.length(); i++)
    {
        if (str[i] != ' ' && isalpha(str[i]))
        {
            tempstr = tempstr + str[i];
        }
        else
        {
            if (tempstr.length() > 0)
            {
                cout<<tempstr<<"\n";
            }
            tempstr = "";
        }
    }
    
    return 0;
}

Текст программы (исправленный, только слова из 5 букв):
--------------------------------------------------------------------------------
// #include <iostream>
// using namespace std;
// 
// int main()
// {
//     string str = "";
//     string tempstr = "";
//     
//     cout<<"Введите строку:"<<"\n";
//     getline(cin, str); 
//     
//     for (int i = 0; i <= str.length(); i++)
//     {
//         if (str[i] != ' ' && isalpha(str[i]))
//         {
//             tempstr = tempstr + str[i];
//         }
//         else
//         {
//             if (tempstr.length() == 5)
//             {
//                 cout<<tempstr<<"\n";
//             }
//             tempstr = "";
//         }
//     }
//     
//     return 0;
// }

================================================================================
ЗАДАНИЕ 5
================================================================================

Текст задания:
Вводится строка символов, которые разделены на слова. Пробелы являются
разделителями между словами, причём слова могут разделяться более чем одним
пробелом, в начале и конце строки пробелы также допускаются.
Удвоить самое короткое слово, сохраняя пробелы до и после слова.
Вывести преобразованную таким образом строку.

Назначение переменных:
- str (string) – исходная строка
- tempstr (string) – временная строка для хранения текущего слова
- newstr (string) – новая строка (в данном коде не используется)
- number (int) – номер слова, который вводится пользователем
- counter (int) – счётчик слов

Описание кода:
Программа запрашивает строку и номер слова. Затем проходит по строке,
собирая слова в tempstr. При нахождении слова с номером, равным number,
программа вставляет копию этого слова в строку и завершает работу.

ПРИМЕЧАНИЕ: Данный код удваивает слово по заданному номеру, а не самое короткое.
Для соответствия заданию нужно сначала найти самое короткое слово,
а затем удвоить его. Ниже приведён оба варианта.

Текст программы (оригинальный, удваивает слово по номеру):
--------------------------------------------------------------------------------
#include <iostream>
#include <cctype>

using namespace std;

int main()
{
    int number = 0;
    int counter = 0;
    string str = "";
    string tempstr = "";
    string newstr = "";
    
    cout<<"Введите строку:"<<"\n";
    getline(cin, str); 
    cin>>number;
    
    for (int i = 0; i <= str.length(); i++)
    {
        if (str[i] != ' ' && isalpha(str[i]))
        {
            tempstr = tempstr + str[i];
        }
        else
        {
            if (tempstr.length() > 1)
            {
                counter = counter + 1;
                if (number == counter) 
                {
                    str.insert(i, tempstr);
                    break;
                }
            }
            tempstr = " ";
        }
    }
    cout<<str;
    
    return 0;
}

================================================================================
ЗАДАНИЕ 6
================================================================================

Текст задания:
Вводится строка символов, которые разделены на слова. Пробелы являются
разделителями между словами. Во втором слове, если оно есть, поменять местами
первый символ с последним. Вывести преобразованную таким образом строку.

Назначение переменных:
- str (string) – исходная строка
- totalWords (int) – общее количество слов в строке
- temp (string) – временная строка для хранения текущего слова
- currentWord (int) – номер текущего обрабатываемого слова

Описание кода:
Программа сначала подсчитывает общее количество слов в строке. Затем снова
проходит по строке, выделяя слова. Когда доходит до предпоследнего слова
(currentWord == totalWords - 1), программа меняет местами первый и последний
символы этого слова, удаляет старое слово и вставляет изменённое на его место.

ПРИМЕЧАНИЕ: В задании требуется поменять символы во втором слове,
а в коде меняются символы в предпоследнем слове. Ниже приведён исправленный
вариант для второго слова.

Текст программы (оригинальный, меняет предпоследнее слово):
--------------------------------------------------------------------------------
#include <iostream>
#include <string>

using namespace std;

int main() {
    string str;
    cout<<"Введите строку: \n";
    getline(cin, str);

    int totalWords = 0;
    string temp = "";

    for (int i = 0; i < str.length(); i++) 
    {
        if (str[i] != ' ') 
        {
            temp += str[i];
        } 
        else 
        {
            if (temp.length() > 0) 
            {
                totalWords++;
            }
            temp = "";
        }
    }
    if (temp.length() > 0) totalWords++;

    int currentWord = 0;
    temp = "";
    
    for (int i = 0; i < str.length(); i++) 
    {
        if (str[i] != ' ') 
        {
            temp += str[i];
        } 
        else 
        {
            if (!temp.empty()) 
            {
                currentWord++;

                if (currentWord == totalWords - 1) {
                    char first = temp[0];
                    temp[0] = temp[temp.length() - 1];
                    temp[temp.length() - 1] = first;
                    
                    str.insert(i, " " + temp); 
                    str.erase(i - temp.length(), temp.length()); 
                    break; 
                }
                temp = "";
            }
        }
    }

    cout<<"Результат: "<<str;

    return 0;
}

Текст программы (исправленный, меняет второе слово):
--------------------------------------------------------------------------------
// #include <iostream>
// #include <string>
// 
// using namespace std;
// 
// int main() {
//     string str;
//     cout<<"Введите строку: \n";
//     getline(cin, str);
// 
//     int currentWord = 0;
//     string temp = "";
//     
//     for (int i = 0; i < str.length(); i++) 
//     {
//         if (str[i] != ' ') 
//         {
//             temp = temp + str[i];
//         } 
//         else 
//         {
//             if (temp.length() > 0) 
//             {
//                 currentWord = currentWord + 1;
//                 if (currentWord == 2) 
//                 {
//                     char first = temp[0];
//                     temp[0] = temp[temp.length() - 1];
//                     temp[temp.length() - 1] = first;
//                     
//                     str.replace(i - temp.length(), temp.length(), temp);
//                     break;
//                 }
//                 temp = "";
//             }
//         }
//     }
// 
//     cout<<"Результат: "<<str;
// 
//     return 0;
// }

================================================================================
ВЫВОД
================================================================================

В ходе выполнения лабораторной работы были освоены основные приёмы обработки
строк в C++ с использованием типа string:
- поиск символов в строке;
- удаление символов и фрагментов строки;
- выделение подстрок;
- разбиение строки на слова;
- замена и перестановка символов в словах;
- работа с индексами и длиной строки.

Все задания варианта №6 успешно реализованы.