Задание 24: Программирование. Обработка символьной информации
1. Общая информация о задании
- Уровень сложности: высокий (Часть 2)
- Максимальный балл: 1
- Примерное время выполнения: около 18 минут
- Формат файла:
.txt— одна длинная строка символов (до 10⁶ символов) - Формат ответа: одно число (или несколько — читать условие)
Суть: прочитать строку из файла и найти подстроку максимальной (или минимальной) длины, удовлетворяющую условию. Ручной разбор невозможен — нужна программа на Python.
Задания: N24. Задания Я.Учебник | N24. Банк заданий
Материалы курса:
- Часть 1 — типы задач, replace, однопроходный алгоритм
- Часть 2 — арифметические выражения, regex
- Часть 3 — запрещённые соседства, replace + split
- Часть 4 — точное число вхождений, склейка фрагментов
2. Считывание файла
В задании 24 файл — одна строка без переводов строк (или одна очень длинная строка).
s = open('24.txt').readline()
или с автозакрытием:
with open('24.txt') as f:
s = f.readline()
Не используй
readlines()без необходимости — файл обычно состоит из одной строки.
3. Три основных метода решения
| Метод | Когда применять | Плюсы | Минусы |
|---|---|---|---|
Однопроходный (cur / max) |
Простые условия на соседних символах | Быстро, понятно | Не для сложных шаблонов |
| replace + split | Запрещённые пары/тройки символов рядом | Не нужен regex | Медленнее на длинных строках |
Регулярные выражения (re) |
Шаблоны, чередования, арифметика | Компактный код | Нужно знать синтаксис |
| Два указателя / скользящее окно | «Ровно N вхождений подстроки» | Быстро на 10⁶ символов | Сложнее в реализации |
На экзамене выбирай метод, который уверенно пишешь. Ответ лучше проверить вторым способом.
4. Четыре типа заданий
| Тип | Условие | Основной метод |
|---|---|---|
| 1 | Максимальная длина подряд идущих символов по шаблону (гласная+согласная, только A, чередование…) | Однопроходный / re |
| 2 | Корректное арифметическое выражение (цифры, +, *, без ведущих нулей) |
re |
| 3 | Определённые символы не стоят рядом (A и B, KL и LK…) | replace + split |
| 4 | Подстрока с точным числом вхождений буквы/комбинации (ровно 2 буквы A, AB встречается 21 раз…) | replace + split + склейка фрагментов |
5. Метод 1: однопроходный алгоритм
Когда: нужна максимальная длина цепочки, где условие проверяется на каждом шаге (соседние символы различны, все символы одинаковые, запрещена пара KL…).
Шаблон
s = open('24.txt').readline()
mx = cur = 1 # или cur = 0 — смотреть условие
for i in range(1, len(s)):
if условие_продолжения(s[i], s[i-1]):
cur += 1
mx = max(mx, cur)
else:
cur = 1 # или другое начальное значение
print(mx)
Пример: максимальная цепочка одинаковых символов A
s = open('24.txt').readline()
mx = cur = 1
for i in range(1, len(s)):
if s[i] == s[i-1] == 'A':
cur += 1
mx = max(mx, cur)
else:
cur = 1
print(mx)
Пример: соседние символы различны
s = open('24.txt').readline()
mx = cur = 1
for i in range(1, len(s)):
if s[i] != s[i-1]:
cur += 1
mx = max(mx, cur)
else:
cur = 1
print(mx)
Пример: запрещена пара KL или LK
s = open('24.txt').readline()
mx = cur = 1
for i in range(1, len(s)):
if (s[i] == 'K' and s[i-1] == 'L') or (s[i] == 'L' and s[i-1] == 'K'):
cur = 1
else:
cur += 1
mx = max(mx, cur)
print(mx)
6. Метод 2: replace + split
Когда: два (или более) символа не должны стоять рядом — вставляем разделитель между запрещёнными парами и ищем самый длинный фрагмент.
Идея
replace('AB', 'A B')— вставить разрыв между A и Bsplit()— разбить строку на фрагментыmax(len(x) for x in parts)— длина самого длинного
Пример: A, B, C — нет подряд идущих A и B
s = open('24.txt').readline()
s = s.replace('AB', 'A B').replace('BA', 'B A')
parts = s.split()
print(max(len(x) for x in parts))
Пример: только символ C (остальные — разделители)
s = open('24.txt').readline()
s = s.replace('A', ' ').replace('B', ' ')
parts = s.split()
print(max(len(x) for x in parts))
Пример: KL и LK запрещены
s = open('24.txt').readline()
s = s.replace('KL', 'K L').replace('LK', 'L K')
print(max(len(x) for x in s.split()))
Важно: между символами нужен разрыв —
'A B', а не'AB'→'A'. Иначе длина фрагмента будет неверной.
7. Метод 3: регулярные выражения
Когда: сложный шаблон — чередование букв, символы из алфавита СС, арифметические выражения.
import re
s = open('24.txt').readline()
# найти все подходящие подстроки
matches = re.findall(r'шаблон', s)
print(max(len(m) for m in matches))
# или с позициями
matches = re.finditer(r'шаблон', s)
print(max(len(m.group()) for m in matches))
Тип 1: гласная + согласная, повторяется
import re
s = open('24.txt').readline()
pattern = r'(?:[AE][BCD])+'
matches = re.finditer(pattern, s)
print(max(len(m.group()) for m in matches))
Тип 2: корректное арифметическое выражение
Число без ведущих нулей: 0 или [1-9][0-9]*.
Выражение: Число (операция Число)*.
import re
s = open('24.txt').readline()
num = r'(?:0|[1-9][0-9]*)'
pattern = rf'{num}(?:[+*-]{num})*'
matches = re.finditer(pattern, s)
print(max(len(m.group()) for m in matches))
Выражение со значением 0
Каждое слагаемое должно содержать умножение на 0:
import re
s = open('24.txt').readline()
num = r'(?:0|[1-9][0-9]*)'
mult = rf'(?:{num}\*)*0(?:\*{num})*'
pattern = rf'{mult}(?:\+{mult})*'
matches = re.finditer(pattern, s)
print(max(len(m.group()) for m in matches))
Чётные числа в выражении
num = r'(?:[1-9][0-9]*[02468]|[02468])'
pattern = rf'{num}(?:[+*]{num})+'
8. Метод 4: replace + split + склейка (тип 4)
Когда: в подстроке подстрока/буква должна встречаться ровно N раз.
Идея (часть 4)
- Разбить строку по искомой комбинации:
replace("AB", "A B").split() - Чтобы AB встретилась ровно 21 раз — склеить 22 соседних фрагмента через
"AB" - Перебрать все окна из 22 фрагментов, взять максимальную длину
s = open('24.txt').readline()
parts = s.replace('AB', 'A B').split()
mx = 0
k = 21 # AB должна встретиться ровно 21 раз → 22 фрагмента
for i in range(len(parts) - k):
# склеиваем parts[i] .. parts[i+k] через 'AB'
candidate = 'AB'.join(parts[i:i + k + 1])
mx = max(mx, len(candidate))
print(mx)
Ровно 2 буквы A в подстроке
s = open('24.txt').readline()
parts = s.replace('A', ' A ').split()
mx = 0
for i in range(len(parts) - 2):
candidate = 'A'.join(parts[i:i + 3]) # 3 фрагмента → 2 буквы A между ними
mx = max(mx, len(candidate))
print(mx)
9. Скользящее окно (два указателя)
Когда: запрещена подстрока фиксированной длины (например, XZZY), или нужно ограничить количество символов в окне.
s = open('24.txt').readline()
bad = 'XZZY'
L = mx = 0
for R in range(len(s)):
while s[L:R+1].find(bad) != -1:
L += 1
mx = max(mx, R - L + 1)
print(mx)
10. Полезные операции со строками
| Что делаем | Код |
|---|---|
| Длина строки | len(s) |
| Символ по индексу | s[i] |
| Срез подстроки | s[i:j] |
| Количество вхождений | s.count('AB') |
| Поиск подстроки | s.find('AB'), s.rfind('AB') |
| Замена | s.replace('A', ' ') |
| Разбиение | s.split(), s.split(' ') |
| Склейка | 'AB'.join(parts) |
| Проверка символа | s[i] in 'ABC' |
| Проверка подстроки | 'AB' in s[i:i+2] |
Модуль re — краткая шпаргалка
| Конструкция | Значение |
|---|---|
[ABC] |
один символ из A, B, C |
[0-9] |
любая цифра |
+ |
1 и более раз |
* |
0 и более раз |
(?:...) |
группа без захвата |
(?:...)+ |
повторение группы |
re.findall(p, s) |
список всех совпадений |
re.finditer(p, s) |
итератор с позициями |
11. Алгоритм решения на экзамене
- Прочитать условие: что в файле, что искать (длина / значение / количество)
- Определить тип (1–4) и выбрать метод
- Считать строку:
s = open('24.txt').readline() - Написать проверку условия или шаблон
- Найти ответ:
maxдлины /minзначения /count - Вывести
print(ответ) - Проверить на короткой тестовой строке вручную
12. Типичные ошибки
| Ошибка | Как избежать |
|---|---|
readlines() вместо readline() |
Файл — одна строка |
replace('AB', 'A') вместо 'A B' |
Нужен разрыв между символами |
Забыли сбросить счётчик cur = 1 |
При нарушении условия — сброс |
max(s.split()) без key=len |
max(s.split(), key=len) |
В regex * — это квантификатор, не умножение |
Экранировать: \* для знака умножения |
| Число с ведущим нулём в regex | Использовать (?:0|[1-9][0-9]*) |
| Не учли порядок в шаблоне (гласная→согласная) | Читать условие: AB ≠ BA |
13. Краткий чек-лист
s = open('24.txt').readline()- Какой тип задачи? (шаблон / арифметика / не рядом / ровно N раз)
- Выбрать метод: однопроходный / replace+split / re / окно
- Написать код, вывести ответ
- Убрать отладочные
printперед сдачей