Задание 24: обработка символьной строки из файла
Работаем с очень длинной строкой символов: ищем самую длинную серию одинаковых букв и считаем вхождения шаблонов.
Серия (цепочка) — это максимальный участок строки из подряд идущих одинаковых символов.
Что проверяет задание 24
Задание 24 — повышенный уровень, 1 балл. К ЕГЭ прилагается файл с одной очень длинной строкой (часто из ограниченного набора букв, например только A, B, C). Типичные вопросы: «Какова длина самой длинной серии одинаковых символов?», «Сколько раз встречается заданная подстрока?», «Какова максимальная длина участка без буквы X?». Строка большая — нужен один проход по символам.
Теория: один проход с «текущей серией»
Чтобы найти самую длинную серию, идём по строке и поддерживаем длину текущей серии cur: если символ совпал с предыдущим — увеличиваем cur, иначе начинаем новую серию (cur = 1). Параллельно обновляем максимум. Это классический приём «сканирование с накоплением» за один проход.
cur = 1
для каждого символа, начиная со второго:
если он равен предыдущему: cur += 1
иначе: cur = 1
обновить максимум max(best, cur)
Чтение строки из файла
with open("24.txt") as f:
s = f.readline().strip() # одна длинная строка без перевода в конце
Разбор примера
Дана строка из букв A, B, C. Нужно найти длину самой длинной серии одинаковых букв и саму эту букву. Возьмём строку AABBBCCCCABABBBBBA.
Решение на Python
s = "AABBBCCCCABABBBBBA" # имитация строки из файла
best_len = 1 # длина самой длинной серии
best_ch = s[0] # буква этой серии
cur = 1 # длина текущей серии
for i in range(1, len(s)):
if s[i] == s[i - 1]:
cur += 1
if cur > best_len:
best_len = cur
best_ch = s[i]
else:
cur = 1
print("Длина макс. серии:", best_len)
print("Буква серии:", best_ch)
Вывод:
Длина макс. серии: 5 Буква серии: B
Самая длинная серия — пять букв B в конце (BBBBB). Серия CCCC длиной 4 — короче. Один проход по строке решает задачу даже для миллионов символов.
Подсчёт вхождений подстроки
Часто спрашивают, сколько раз встречается шаблон, например «AB». Метод строки count считает непересекающиеся вхождения слева направо.
s = "ABABABXABAB"
print("Вхождений 'AB':", s.count("AB"))
print("Вхождений 'ABA':", s.count("ABA")) # непересекающиеся!
Вывод:
Вхождений 'AB': 5 Вхождений 'ABA': 2
Обратите внимание: count не считает пересекающиеся вхождения. «ABABA» содержит «ABA» дважды по позициям, но count найдёт только одно (после совпадения он продолжает с конца найденного). Если в задаче нужны пересекающиеся вхождения — считайте циклом по всем позициям.
s = "ABABABA"
pattern = "ABA"
overlapping = sum(1 for i in range(len(s) - len(pattern) + 1)
if s[i:i + len(pattern)] == pattern)
print("Пересекающихся вхождений 'ABA':", overlapping)
Вывод:
Пересекающихся вхождений 'ABA': 3
В строке «ABABABA» подстрока «ABA» начинается на позициях 0, 2 и 4 — три раза, если разрешено перекрытие. count даёт только непересекающиеся, поэтому всегда уточняйте формулировку: «сколько раз встречается» обычно означает непересекающиеся, но «на скольких позициях начинается» — это перекрытия.
Самый длинный участок без заданной буквы
Ещё один частый вопрос: «Какова наибольшая длина участка, не содержащего букву X?» Это та же идея «текущей длины», но сбрасываем счётчик не при смене символа, а при встрече запретной буквы.
s = "AABXCCCCXBBXCC" # ищем самый длинный участок без 'X'
forbidden = "X"
best = 0 # лучшая длина участка без X
cur = 0 # длина текущего участка без X
for ch in s:
if ch == forbidden:
cur = 0 # встретили X — участок прерван
else:
cur += 1
if cur > best:
best = cur
print("Самый длинный участок без 'X':", best)
Вывод:
Самый длинный участок без 'X': 4
Между двумя буквами X стоит «CCCC» длиной 4 — это и есть ответ. Обратите внимание: счётчик cur сбрасывается ровно на запретной букве, а максимум обновляется на каждом шаге роста. Тот же шаблон годится для «участок без гласных», «без повторов» и подобных формулировок — меняется только условие сброса.
Замена и подсчёт через метод count для одного символа
Если нужно просто сосчитать, сколько раз встречается один символ (а не подстрока и не серия), хватит str.count или сравнения в генераторе.
s = "AABBBCCCCABABBBBBA"
print("Букв 'B' всего:", s.count("B"))
print("Букв 'C' всего:", sum(1 for ch in s if ch == "C"))
Вывод:
Букв 'B' всего: 9 Букв 'C' всего: 4
Типичные ошибки
- Не обновляют максимум вовремя. Максимум проверяют на каждом шаге увеличения серии, а не только в конце.
- Путают пересекающиеся и непересекающиеся вхождения.
count— непересекающиеся; для пересекающихся нужен явный цикл. - Забывают
strip()при чтении. Перевод строки в конце может исказить последнюю серию. - Стартуют максимум с нуля при пустой обработке. Для непустой строки минимальная серия — 1, начинайте с 1.
Итог
- Самая длинная серия — один проход с переменной текущей серии и обновлением максимума.
- Для подсчёта подстрок
str.countсчитает непересекающиеся вхождения; пересекающиеся — циклом по позициям. - При чтении строки делайте
strip(), чтобы убрать перевод строки.