Решения | C# и VB.NET | Обработка строк
модуля PT4Load. В созданный проект будет входить файл с именем String9; его расширение зависит от выбранного языка: .cs для C# и .vb для VB.NET. Приведем текст процедуры Solve из данного файла (именно в эту процедуру требуется ввести решение задачи):
[C#]
public static void Solve() { Task("String9"); }
[VB.NET]
Sub Solve() Task("String9") End Sub
После запуска программы на экране появится окно задачника. На рисунке приведены два варианта представления окна (в режиме с динамической и с фиксированной компоновкой) в случае использования языка C#:


Данные символьного и строкового типа в окне задачника заключаются в кавычки; это позволяет, в частности, отличить числовые данные (например, 2) от символьных и строковых данных, содержащих цифры (например, строки "2"). Кроме того, кавычки дают возможность увидеть пробелы, находящиеся в начале или в конце строк.
Ввод исходных данных
Добавим в процедуру Solve фрагмент, обеспечивающий ввод исходных данных. При этом будем учитывать, что данные символьного типа надо вводить с помощью функции GetChar, а данные целого типа с помощью функции GetInt:
[C#]
public static void Solve() { Task("String9"); char c1 = GetChar(), c2 = GetChar(); int n = GetInt(); }
[VB.NET]
Sub Solve() Task("String9") Dim c1 As Char = GetChar(), c2 As Char = GetChar() Dim n As Integer = GetInt() End Sub
Мы намеренно ввели данные не в том порядке, в котором они указаны в окне задачника.
Запуск нового варианта программы уже не будет считаться ознакомительным, поскольку в программе выполняется ввод исходных данных. Так как порядок ввода исходных данных является ошибочным, этот вариант решения будет признан неверным и приведет к сообщению «Неверно указан тип при вводе исходных данных. Для ввода 1-го элемента (целого типа) использована переменная символьного типа».
Напомним правило, определяющее порядок ввода и вывода данных для задачника Programming Taskbook: ввод и вывод данных производится по строкам (слева направо), а строки просматриваются сверху вниз.
Исправим процедуру Solve, изменив в ней порядок ввода исходных данных:
[C#]
int n = GetInt(); char c1 = GetChar(), c2 = GetChar();
[VB.NET]
Dim n As Integer = GetInt() Dim c1 As Char = GetChar(), c2 As Char = GetChar()
Теперь исходные данные вводятся правильно. Однако из-за того что в программе отсутствует вывод результирующих данных, решение снова будет признано ошибочным; при этом на информационной панели появится сообщение «Выведены не все результирующие данные. Количество выведенных данных: 0 (из 1)»
Формирование требуемой строки и ее вывод
Для формирования нужной строки воспользуемся операцией сцепления строк («+» в языке C#, «&» в языке VB.NET), после чего выведем полученную строку методом Put:
[C#]
public static void Solve() { Task("String9"); int n = GetInt(); char c1 = GetChar(), c2 = GetChar(); string s = ""; for (int i = 0; i < n; i++) s = s + c1 + c2; Put(s); }
[VB.NET]
Sub Solve() Task("String9") Dim n As Integer = GetInt() Dim c1 As Char = GetChar(), c2 As Char = GetChar() Dim s As String = "" For i As Integer = 1 To n s = s & c1 & c2 Next Put(s) End Sub
В варианте для VB.NET обратите внимание на новую для языка Visual Basic возможность описания переменной цикла непосредственно в заголовке цикла.
При выполнении этой программы в области результатов будет выведена строка, оканчивающаяся особым символом красной звездочкой, например:
"a1a1a1a1a1*
Красная звездочка, расположенная в конце строки, отображаемой на экране, означает, что длина полученной строки превышает длину контрольной (т. е. «правильной») строки. Для того чтобы увидеть на экране всю полученную строку, достаточно подвести курсор мыши к строке со звездочкой; при этом полный текст строки появится во всплывающей подсказке.
Примечание. Красная звездочка может появиться и при выводе ошибочных числовых данных. Например, если ожидается целое число в диапазоне от 1 до 99, а получено число 10000, то на экран будет выведена только первая цифра этого числа, за которой будет указана красная звездочка: 1*.
Правильное решение, его тестирование и просмотр результатов
Ошибка в предыдущей программе возникла из-за неверного указания количества итераций цикла. Действительно, на каждой итерации к строке добавляется по два символа, поэтому после n итераций строка будет содержать 2n символов (а не n, как требуется в задании).
Для исправления ошибки достаточно вдвое уменьшить число итераций, изменив заголовок цикла следующим образом (обратите внимание на использование операции целочисленного деления \ в заголовке цикла для языка VB.NET):
[C#]
for (int i = 0; i < n / 2; i++)
[VB.NET]
For i As Integer = 1 To n \ 2
После запуска исправленной программы мы получим сообщение «Верное решение. Тест номер 1 (из 5)», а после пяти подобных запусков сообщение «Задание выполнено!». Нажав клавишу [F2], мы можем вывести на экран окно результатов, в котором будут перечислены все наши попытки решения задачи (заглавная буква «S», которая указывается перед датой, означает, что при выполнении задания использовался язык C# «C Sharp»):
String9 S24/03 11:37 Ознакомительный запуск. String9 S24/03 11:48 Неверно указан тип при вводе исходных данных. String9 S24/03 11:49 Выведены не все результирующие данные. String9 S24/03 11:49 Ошибочное решение. String9 S24/03 11:52 Задание выполнено!
В случае выполнения задания на языке VB.NET перед датой указывается буква «B» «Basic» (для обозначения языков платформы .NET в окне результатов используются заглавные буквы).
Примечание. С использованием класса StringBuilder задачу можно решить, заполняя требуемую строку посимвольно. Приведем полный текст файлов String9.cs и String9.vb с соответствующим вариантом решения:
[String9.cs]
using System; using System.Text; using PT4;
namespace PT4Tasks { public class MyTask: PT { public static void Solve() { Task("String9"); int n = GetInt(); char c1 = GetChar(), c2 = GetChar(); StringBuilder s = new StringBuilder(n); s.Length = n; for (int i = 0; i < n / 2; i++) { s[2 * i] = c1; s[2 * i + 1] = c2; } Put(s.ToString()); } } }
[String9.vb]
Option Strict On Imports System Imports System.Text
Imports PT4.PT Module PT4Tasks Sub Solve() Task("String9") Dim n As Integer = GetInt() Dim c1 As Char = GetChar(), c2 As Char = GetChar() Dim s As New StringBuilder(n) s.Length = n For i As Integer = 0 To n \ 2 - 1 s(2 * i) = c1 s(2 * i + 1) = c2 Next Put(s.ToString()) End Sub End Module
Следует обратить внимание на указание в начале программы пространства имен System.Text (в котором описан класс StringBuilder), а также на преобразование объекта s к «обычному» строковому типу string при его выводе (если попытаться вывести результат без такого преобразования, т. е. в виде Put(s), то задачник выведет сообщение об ошибке «В методе Put указан параметр недопустимого типа StringBuilder»).
В конструкторе StringBuilder указывается переменная n; это позволяет задать емкость строки s (т. е. размер массива символов, используемого для хранения данной строки). Однако длина созданной строки s (т. е. количество фактически содержащихся в ней символов) остается равной 0, и для того чтобы положить ее равной нужной длине, требуется изменить свойство s.Length. Необходимость использования класса StringBuilder объясняется тем, что обычные строки (типа string) являются неизменяемыми; в частности, их символы и свойство Length доступны только для чтения.