Выполнение задания на обработку строк: String9
Особенности выполнения заданий на обработку символов и строк рассмотрим на
примере задания String9.
String9°. Дано четное число N (> 0)
и символы C1 и C2. Вывести строку длины N,
которая состоит из чередующихся символов C1 и C2,
начиная с C1.
Создание программы-заготовки и знакомство с заданием
Проект-заготовку для решения задачи String9 можно создать с помощью
модуля PT4Load. Приведем текст функции Solve из файла String9.cpp, входящего в
созданный проект (именно в эту функцию требуется ввести решение задачи):
[C/C++]
void Solve()
{
Task("String9");
}
Функция Solve для языка C выглядит аналогичным образом.
После запуска программы на экране появится окно задачника. На рисунке
приведены два варианта представления окна в режиме с динамической
и с фиксированной компоновкой:
Символьные данные в окне задачника заключаются в
одинарные и двойные кавычки соответственно; это позволяет отличить числовые
данные (например, 2) от символьных и строковых данных, содержащих цифры
(например, символа '2'). Кроме того, кавычки дают возможность увидеть пробелы,
находящиеся в начале или в конце строк.
Символьные данные в языках C и C++ имеют тип char, строковые данные могут храниться в виде
символьных массивов (типа char* или char[]), а также, для языка C++, в виде объектов-строк типа std::string.
Ввод исходных данных
Добавим в функцию Solve фрагмент, обеспечивающий ввод исходных данных.
Для ввода данных типа char и int на языке C необходимо использовать функции GetC и GetN. Эти же функции
можно применять и в программах на языке C++, однако в них
проще воспользоваться специальным потоком ввода-вывода pt:
[C/C++]
Task("String9");
int n;
char c1, c2;
GetC(&c1);
GetC(&c2);
GetN(&n);
[C++]
Task("String9");
int n;
char c1, c2;
pt >> c1 >> c2 >> n;
Мы намеренно ввели данные не в том порядке, в котором они указаны в окне
задачника.
Запуск нового варианта программы уже не будет считаться ознакомительным,
поскольку в программе выполняется ввод исходных данных. Так как порядок ввода
исходных данных является ошибочным, этот вариант решения будет признан
неверным и приведет к сообщению «Неверно указан тип при вводе исходных
данных. Для ввода 1-го элемента (целого типа) использована переменная символьного
типа».
Напомним правило, определяющее порядок ввода и вывода данных для
задачника Programming Taskbook: ввод и вывод данных производится по строкам
(слева направо), а строки просматриваются сверху вниз.
Исправим функцию Solve, изменив в ней порядок ввода исходных данных:
[C/C++]
GetN(&n);
GetC(&c1);
GetC(&c2);
[C++]
pt >> n >> c1 >> c2;
Теперь исходные данные вводятся правильно. Первый этап решения задачи пройден.
Формирование требуемой строки и ее вывод
При решении задач на обработку строк на языке C необходимо использовать
символьные массивы и набор специальных функций, входящих в стандартную библиотеку C
(и описанных в заголовочном файле <string.h>). Полученное решение
можно использовать и для языка C++ (подключив к программе заголовочный файл <cstring>),
однако для этого языка удобнее использовать стандартный класс std::string
(описанный в заголовочном файле <string>).
Напомним, что для подключения стандартных заголовочных файлов надо использовать директиву #include,
например:
[C]
#include <string.h>
[C++]
#include <string>
Кроме того, чтобы не указывать стандартное пространство имен std перед именем стандартных типов языка C++,
можно добавить к программе на этом языке следующую директиву:
[C++]
using namespace std;
Заметим, что эта директива автоматически добавляется во все создаваемые заготовки для заданий на языке C++.
Вначале приведем решение на языке C, которое можно использовать и для языка C++. В нем мы опишем символьный массив s достаточно большого размера
(при выполнении любых заданий, связанных с обработкой строковых данных,
достаточно использовать символьные массивы размера 80)
и заполним его поэлементно, не забыв добавить в конец записанного набора символов особый нулевой символ '\0',
являющийся признаком конца строки (вместо нулевого символа достаточно использовать число 0). Для вывода полученной строки в задачнике предусмотрена функция PutS
(функция для ввода строки, записывающая строку в символьный массив, имеет имя GetS).
[C/C++]
char s[80];
int p = 0;
for (int i = 0; i < n; ++i)
{
s[p++] = c1;
s[p++] = c2;
}
s[p] = 0;
PutS(s);
Для языка C++ можно получить более краткий вариант решения, если использовать тип string
и определенную для него операцию «+» сцепления строк
(при описании переменной типа string в нее автоматически заносится пустая строка).
Кроме того, для этого языка можно вывести полученную строку с помощью потока вывода pt:
[C++]
string s;
for (int i = 0; i < n; ++i)
s = s + c1 + c2;
pt << s;
}
Однако при выполнении любой из полученных программ в области результатов будет выведена строка,
оканчивающаяся особым символом красной звездочкой, например:
"a1a1a1a1a1*
Красная звездочка, расположенная в конце строки, отображаемой на экране,
означает, что длина результирующей строки превышает длину контрольной (т. е.
«правильной») строки. Для того чтобы увидеть на экране всю
полученную строку, достаточно подвести курсор мыши к строке со звездочкой; при
этом полный текст строки появится во всплывающей подсказке.
Правильное решение, его тестирование и просмотр результатов
Ошибка в предыдущих программах возникла из-за неверного указания количества
итераций цикла. Действительно, на каждой итерации к строке добавляется по два
символа, поэтому после n итераций строка будет содержать 2n символов (а не n, как
требуется в задании).
Для исправления ошибки достаточно вдвое уменьшить число итераций, изменив
заголовок цикла следующим образом:
[C/C++]
for (int i = 0; i < n / 2; ++i)
После запуска исправленной программы и успешного прохождения 5 тестов
мы получим сообщение «Задание выполнено!». Нажав клавишу [F2],
мы можем вывести на экран окно результатов, в
котором будут перечислены все наши попытки решения задачи (буква «c», которая
указывается перед датой, означает, что при выполнении задания использовался язык
C++; для языка C используется заглавная буква «C»):
String9 c24/03 11:37 Ознакомительный запуск.
String9 c24/03 11:48 Неверно указан тип при вводе исходных данных.
String9 c24/03 11:49 Запуск с правильным вводом данных.
String9 c24/03 11:49 Ошибочное решение.
String9 c24/03 11:52 Задание выполнено!
[C/C++]
Task("String9");
int n;
char c1, c2;
GetN(&n);
GetC(&c1);
GetC(&c2);
char s[80];
for (int i = 0; i < n / 2; ++i)
{
s[2 * i] = c1;
s[2 * i + 1] = c2;
}
s[n] = 0;
PutS(s);
Приведем также полный вариант решения для языка C++, использующий тип string:
[C++]
Task("String9");
int n;
char c1, c2;
pt >> n >> c1 >> c2;
string s;
for (int i = 0; i < n / 2; ++i)
s = s + c1 + c2;
pt << s;
|