ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.12.2023
Просмотров: 2648
Скачиваний: 17
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
© К. Поляков, 2018-2022
24 (высокий уровень, время – 18 минут)
Тема: Обработка символьных строкЧто проверяется:Умение создавать собственные программы (10–20 строк) для обработки символьной информации.1.5.2. Цепочки (конечные последовательности), деревья, списки, графы, матрицы (массивы), псевдослучайные последовательности.1.1.3. Строить информационные модели объектов, систем и процессов в виде алгоритмов.Что нужно знать:-
сначала нужно прочитать строку из файла; эта задача в разных языках программирования решается несколько по-разному -
в языке Python удобнее всего использовать такую конструкцию:
-
в языке PascalABC.NET можно выполнить перенаправление потока ввода:
-
в языке FreePascal также можно выполнить перенаправление потока ввода, но нужно дополнительно открывать входной поток:
-
при работе в среде FreePascal нужно убедиться, что в параметрах компилятора включена поддержка длинных символьных строк; на всякий случай стоит добавить в первой строке программы директиву
-
Среда PascalABC НЕ ПОДДЕРЖИВАЕТ работу с длинными символьными строками, поэтому для решения задачи использовать версию PascalABC.NET, которую можно бесплатно скачать с сайта автора www.pascalabc.net. -
в языке С++ используем потоки:
-
пусть требуется найти самую длинную цепочку символов С (или каких-то других, в соответствии с заданием) в символьной строке s; -
можно использовать такой алгоритм:
whileне конец строки:найти очередную букву Cдлина := длина текущей цепочки букв Cif длина > максимальной длины:максимальная длина := длинаоднако этот алгоритм содержит вложенный цикл и при составлении программы легко запутаться и не учесть какой-то особый случай (например, когда строка состоит только из букв С)
-
лучше применить однопроходный алгоритм без вложенного цикла
-
будем использовать переменные
-
рассмотрим очередной символ строки; если это буква C, увеличиваем cLen на 1 и, если нужно запоминаем новую максимальную длину; если это не буква C, просто записываем с cLen ноль:
-
проверим правильность работы алгоритма в особых случаях:
-
если вся строка состоит из букв C, значение переменной cLen постоянно увеличивается и в конце станет равно длине символьной строки; то же значение окажется и в переменной maxLen; -
если в строке нет символов C, переменная cLen всегда равна 0, такое же значение будет и в переменной maxLen
-
теперь поставим задачу найти самую длинную цепочку символов в символьной строке s; сложность состоит в том, что мы (в отличие от предыдущей задачи) не знаем, из каких именно символов состоит самая длинная цепочка -
если символов в алфавите немного (скажем, A, B и С), то можно с помощью описанного выше алгоритма найти самые длинные цепочки из букв A, B и C, а затем выбрать из них «длиннейшую»; такая идея может сработать при аккуратной реализации, но плохо обобщается на случай, когда возможных символов много (например, используются все заглавные латинские буквы и цифры) -
поэтому лучше применить однопроходный алгоритм без вложенного цикла -
будем использовать переменные
-
в начальный момент рассмотрим один первый символ (цепочка длины 1 есть всегда!):
maxLen = 1curLen = 1c = s[0]
-
будем перебирать в цикле все символы, начиная с s[1] (второго по счёту) до конца строки, постоянно «оглядываясь назад», на предыдущий символ
-
если очередной символ s[i] такой же, как и предыдущий, цепочка одинаковых символов продолжается, и нужно увеличить значение переменной curLen; если значение curLen стало больше maxLen, обновляем maxLen и запоминаем новый базовый символ в переменной c:
-
получается такой цикл обработки строки:
-
проверим правильность работы алгоритма в особых случаях:
-
если вся строка состоит из одинаковых символов, значение переменной curLen постоянно увеличивается и в конце станет равно длине символьной строки; то же значение окажется и в переменной maxLen; -
если в строке нет пар одинаковых символов, переменная curLen всегда равна 1, такое же значение будет и в переменной maxLen
Пример задания:
Р-07 (демо-2021). Текстовый файл 24.txt состоит не более чем из 106 символов X, Y и Z. Определите максимальное количество идущих подряд символов, среди которых каждые два соседних различны. Для выполнения этого задания следует написать программу. Решение:-
считывание из файла и перебор символов аналогичен задачам Р00-Р02 (см. ниже). -
чтобы считать длину цепочки, соответствующей условию, нам нужно будет ввести два счётчика:
-
обработка строки сводится к тому, что текущая длина цепочки увеличивается, если соседние символы, s[i-1] и s[i], различны; если это не так, сбрасываем длину текущей цепочки в 1 -
можно заметить, что эта задача очень напоминает Р-05, только тут обратное условие – нужно искать цепочку, где все соседние символы не одинаковые, а разные, поэтому и решение сводится к изменению условия (см. выделение маркером):
-
Ответ: 35. -
программа на Паскале:
-
программа на C++:
Пример задания:
Р-06. В текстовом файле k8.txt находится цепочка из символов, в которую могут входить заглавные буквы латинского алфавита A…Z и десятичные цифры. Найдите длину самой длинной подцепочки, состоящей из одинаковых символов. Для каждой цепочки максимальной длины выведите в отдельной строке сначала символ, из которого строится эта цепочка, а затем через пробел – длину этой цепочки. Решение:-
особенность этой задачи в сравнении с Р-05 состоит в следующем: если найдено несколько цепочек одинаковой максимальной длины, для каждой из них нужно вывести символ, из которого состоит цепочка, и длину цепочки -
это значит, что для хранения символа нужна не одна переменная, а массив (в Python – список); если найдена первая цепочка (выполнено условие ) -
итак, теперь c – это массив (список); когда найдена первая цепочка максимальной длины (на данный момент), в этот массив записывается символ этой цепочки; если же найдена новая цепочка такой же длины, в массив добавляется символ этой цепочки -
таким образом, в конце прохода в массиве c находятся все символы, из которых состоят самые длинные цепочки, и остаётся вывести их на экран; справа от каждого символа выводится длина цепочки:
for c1 in c:print( c1, maxLen )
-
вот полная программа (изменения в сравнении с решением задачи Р-05 выделены):
-
проблема состоит в том, что мы не знаем, сколько цепочек максимальной длины может быть в файле; тут нужен динамический массив (список), для этого далее мы будем использовать язык PascalABC.NET, в котором есть тип данных List (список) -
вначале создаём новый список и записываем у него первый символ строки:
-
если нашли новую (не первую) цепочку максимальной длины, добавляем новый символ в список:
-
если нашли новую самую длинную цепочку с длиной бОльшей, чем все предыдущие, очищаем список и добавляем в него новый символ.
-
после окончания обработки нужно вывести все символы и длины цепочек, удобнее всего использовать для этого цикл foreach; получается почти так же, как и на Python:
-
вот полная программа: