Решим задачу олимпиады по информатике для 9-11 классов с помощью регулярных выражений.
Условия задачи:
Капитан Флинт зарыл клад на Острове сокровищ. Он оставил описание, как найти клад. Описание состоит из строки вида: "17N5E4W2S3E", где: "N", "S", "E", "W", – задает направление движения, а число – количество шагов, которое необходимо пройти в этом направлении.
Программа должна вывести маршрут, ведущий в точку с этими же координатами, записанными в таком же виде, как и во входных данных, но она должна использовать минимальное количество символов.
Для данного примера ответ: 15N4E
Логика решения заключается в следующем: Нужно вычислить, сколько всего шагов шел только на север и сколько шагов он шел только на юг. Выяснить в результате он закопал клад северней начальной точки или нет.
Если да, то шаги на юг, отнимаем от шагов на север, иначе наоборот.
Такие же расчеты мы должны провести относительно движения на запад или восток.
Для решения мы будем использовать регулярные выражения:
Регуля́рные выраже́ния (англ. regular expressions) — формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов (символов-джокеров, англ. wildcard characters). Для поиска используется строка-образец (англ. pattern, по-русски её часто называют «шаблоном», «маской»), состоящая из символов и метасимволов и задающая правило поиска. Для манипуляций с текстом дополнительно задаётся строка замены, которая также может содержать в себе специальные символы.
Просто говоря нам нужно спарсить с заданной строки нужные нам последовательности символов. Подгружаем модуль re. Будем использовать его метод findall() - который, с помощью регулярного выражения находит нужную последовательность символов в строке.
\d - означает, что мы ищем цифру
\d+ - значит, что мы будем искать одну или более цифр
N - значит, что далее должна стоять буква N
1-й шаг: Парсим направление и значение
таким образом выражение \d+N - указывает, что нужно искать последовательность цифр и следующую за ним букву N.
Также поступаем и с остальными направлениями. Учитывая, что findall() возвращает список, то захватываем полученные значения в списки:
Если мы выведем полученные списки на экран, то увидим:
2-й шаг: Парсим только значения
На втором шаге из полученных списков спарсим только значения. Разница заключается в том, что findall() принимает строку, поэтому предварительно приводим списки к строке (если Вы прочитали все наши статьи по основам работы Python, Вы понимаете о чем речь). Результат будем захватывать в другие списки:
На данном этапе получим списки со значениями:
3-й шаг: Складываем значения направлений в переменные N,S,E,W. Для этого в цикле перебираем списки поэлементно, приводим элементы к числу и по одному прибавляем друг к другу:
После этого мы имеем четыре переменных, хранящими значения направлений:
4-й шаг: Собираем строку
Собираем строку, которую мы выведем на экран с помощью логики, которую мы описали в начале статьи:
итак:
Фига себе, не только работает, но и с ответом совпадает!!! (шутка)
Для закрепления материала предлагаю вам:
1. Организовать ввод строки пользователя с консоли
2. Провести рефакторинг кода до 23 строк (сейчас 30)
Рефа́кторинг (англ. refactoring), или перепроектирование кода, переработка кода, равносильное преобразование алгоритмов — процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы. В основе рефакторинга лежит последовательность небольших эквивалентных (то есть сохраняющих поведение) преобразований. Поскольку каждое преобразование маленькое, программисту легче проследить за его правильностью, и в то же время вся последовательность может привести к существенной перестройке программы и улучшению её согласованности и чёткости.