Programming Taskbook


E-mail:

Пароль:

Регистрация пользователя   Восстановление пароля

 

ЮФУ SMBU

Электронный задачник по программированию

©  М. Э. Абрамян (Южный федеральный университет, Университет МГУ-ППИ в Шэньчжэне), 1998–2024

 

Решения | Python | Обработка строк

PrevNext


Выполнение задания на обработку строк: String9

Особенности выполнения заданий на обработку символов и строк рассмотрим на примере задания String9.

String9°. Дано четное число N (> 0) и символы C1 и C2. Вывести строку длины N, которая состоит из чередующихся символов C1 и C2, начиная с C1.

Создание программы-заготовки и знакомство с заданием

Программу-заготовку для решения задания String9 можно создать с помощью модуля PT4Load. Программа, созданная для задания String9, имеет следующий вид:

from pt4 import *
def solve():
    task("String9")
  
start(solve)

Запустим программу, нажав клавишу [F5] при работе в среде IDLE, Wing IDE и VS Code. После запуска программы на экране появится окно задачника. На рисунке приведены два варианта представления окна — в режиме с динамической и с фиксированной компоновкой:


Символьные и строковые данные в окне задачника заключаются в двойные кавычки; это позволяет отличить числовые данные (например, 2) от символьных и строковых данных, содержащих цифры (например, символа "2"). Кроме того, кавычки дают возможность увидеть пробелы, находящиеся в начале или в конце строк.

Ввод исходных данных

Добавим в программу фрагмент, обеспечивающий ввод исходных данных. Для ввода данных типа символ и целое число надо использовать функции get_str и get_int:

def solve():
    task("String9")
    a = get_str()
    b = get_str()
    n = get_int()

Мы намеренно ввели данные не в том порядке, в котором они указаны в окне задачника.

Запуск нового варианта программы уже не будет считаться ознакомительным, поскольку в программе выполняется ввод исходных данных. Так как порядок ввода исходных данных является ошибочным, этот вариант решения будет признан неверным и приведет к сообщению «Неверно указан тип при вводе исходных данных. Для ввода 1-го элемента (целого типа) использована переменная символьного типа».

Напомним правило, определяющее порядок ввода и вывода данных для задачника Programming Taskbook: ввод и вывод данных производится по строкам (слева направо), а строки просматриваются сверху вниз.

Примечание. Если бы для ввода исходных данных использовалась «универсальная» функция get, то задачник не обнаружил бы ошибок ввода, однако в результате в переменную a было бы записано целое число, а в переменные b и n — символы. Таким образом, содержимое переменных не соответствовало бы их назначению, что в дальнейшем обязательно привело бы к неправильной работе алгоритма, использующего эти переменные. Приведенный пример показывает преимущества использования специализированных функций ввода, позволяющих сразу распознать типичные ошибки при чтении исходных данных.

Исправим программу, изменив в ней порядок ввода:

def solve():
    task("String9")
    n = get_int()
    a = get_str()
    b = get_str()

Теперь исходные данные вводятся правильно. Первый этап решения задачи пройден.

Формирование требуемой строки и ее вывод

Для формирования нужной строки воспользуемся операцией «+» сцепления строк; для вывода полученной строки используем функцию put:

def solve():
    task("String9")
    n = get_int()
    a = get_str()
    b = get_str()
    s = ""
    for i in range(n)
        s += a + b
    put(s)

При попытке запуска этой программы на экран будет выведено окно с сообщением о синтаксической ошибке в программе:

Подобные сообщения выводятся средой IDLE в случае обнаружения синтаксических ошибок, препятствующих запуску программы. При закрытии диалогового окна в окне с программой будет выделена строка, в которой была найдена ошибка:

В данном случае ошибка заключается в том, что в конце выделенной строки отсутствует двоеточие.

После исправления данной ошибки программа уже не будет содержать синтаксических ошибок. При запуске этой программы в области результатов будет выведена строка, оканчивающаяся особым символом — красной звездочкой, например:

"a1a1a1a1a1*

Красная звездочка, расположенная в конце строки, отображаемой на экране, означает, что длина полученной строки превышает длину контрольной (т. е. «правильной») строки. Для того чтобы увидеть на экране всю полученную строку, достаточно подвести курсор мыши к строке со звездочкой; при этом полный текст строки появится во всплывающей подсказке.

Примечание. Красная звездочка может появиться и при выводе ошибочных числовых данных. Например, если ожидается целое число в диапазоне от 1 до 99, а получено число 10000, то на экран будет выведена только первая цифра этого числа, за которой будет указана красная звездочка: 1*.

Правильное решение, его тестирование и просмотр результатов

Ошибка в предыдущей программе возникла из-за неверного указания количества итераций цикла. Действительно, на каждой итерации к строке добавляется по два символа, поэтому после n итераций строка будет содержать 2n символов (а не n, как требуется в задании).

Для исправления ошибки достаточно вдвое уменьшить число итераций, изменив заголовок цикла следующим образом:

for i in range(n // 2):

Мы использовали специальную операцию целочисленного деления «//». Заметим, что в версиях 2.x можно было бы использовать и обычную операцию деления «/», поскольку в этих версиях при наличии обоих операндов целого типа операция «/» означает операцию целочисленного деления. Однако в языке Python версий 3.x операция «/» всегда всегда означает деление с вещественным результатом, поэтому для выполнения целочисленного деления необходимо пользоваться операцией «//» (в Python 3.x при попытке использования в указанном выше операторе заголовка цикла операции «/» мы получили бы сообщение об ошибке типа TypeError: «'float' object cannot be interpreted as an integer»).

После запуска исправленной программы и успешного прохождения 5 тестов мы получим сообщение «Задание выполнено!». Нажав клавишу [F2], мы можем вывести на экран окно результатов, в котором будут перечислены все наши попытки решения задачи (буква «y», которая указывается перед датой, означает, что при выполнении задания использовался язык Python):

String9     y06/09 15:46 Ознакомительный запуск.
String9     y06/09 15:50 Неверно указан тип при вводе исходных данных.
String9     y06/09 15:55 Запуск с правильным вводом данных.
String9     y06/09 16:00 Ошибочное решение.
String9     y06/09 16:05 Задание выполнено!

Обратите внимание на то, что сообщения об обнаружении синтаксической ошибки (отсутствии двоеточия) в данном списке нет, так как при наличии синтаксических ошибок программа не запускается на выполнение, и поэтому задачник не получает от нее никакой информации.

Примечание. Вместо цикла for в программе можно было бы использовать цикл while, повторяя его итерации до тех пор, пока длина строки не станет равной n. В этом случае нет необходимости прибегать к операции целочисленного деления и, кроме того, не потребуется использовать вспомогательную переменную i.

def solve():
    task("String9")
    n = get_int()
    a = get_str()
    b = get_str()
    s = ""
    while len(s) < n:
        s += a + b
    put(s)

С другой стороны при решении задачи можно вообще обойтись без цикла, если воспользоваться специальной возможностью языка Python: операцией «*», которую можно применять к двум операндам: n (целому числу) и s (строке). Результатом операции n * s (как и s * n) будет строка, содержащая n копий исходной строки s. Таким образом, после ввода исходных данных (который можно организовать в виде одного оператора) в нашей программе останется лишь применить эту операцию:

def solve():
    task("String9")
    n, a, b = get_int(), get_str(), get_str()
    s = n // 2 * (a + b)
    put(s)

Более того, поскольку в используемое выражение можно передать вызовы функций ввода, а результат сразу указать в качестве параметра функции put, данный вариант решения можно сжать до одного оператора (не считая операторов импортирования модуля pt4 и вызова функции task):

def solve():
    task("String9")
    put(get_int() // 2 * (get_str() + get_str()))

Еще более краткий (хотя и менее наглядный) вариант решения может быть получен при использовании «универсальной» функции ввода get:

def solve():
    task("String9")
    put(get() // 2 * (get() + get()))

PrevNext

 

Рейтинг@Mail.ru

Разработка сайта:
М. Э. Абрамян, В. Н. Брагилевский

Последнее обновление:
01.01.2024