Читать книгу: «Занимательное программирование – игры с текстом», страница 2

Шрифт:

Задача 1

Дана строка символов. Удалить из нее первый знак препинания.

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

Реализуем эту идею на Паскале:



Проанализируем этот листинг.

1. Вводится строка и определяется ее длина dl (при помощи стандартной функции Lenght).

2. Переменная k, которая у нас одновременно будет служить для запоминания позиции найденного первого знака препинания и играть роль «флага», обнуляется.

3. Строится цикл for перебора значения переменной i от 1 до значения длины строки dl.

4. В теле цикла мы должны извлечь очередной (записанный в позиции i) символ строки. И вот здесь проявляется удобство «дуализма» обращения к строкам в языке Паскаль: вместо того, чтобы, как в Бейсике, записывать каждый раз функцию, извлекающую нужный символ как подстроку (в Бейсике: MID$(ST$,I,1), в Паскале – Copy(st,i,1) ), мы можем просто обратиться сразу к требуемому символу как к элементу массива st с индексом i: st[i].

5. Очередной символ (st[i]) нужно сравнивать с каждым из возможных символов – знаков препинания, записывая операции сравнения типа st[i] = '.' через логическую связку or в операторе if. Тогда в ветви then (т.е. если очередной символ строки равен хотя бы одному знаку препинания) мы запоминаем его номер позиции (i) в переменной k и прерываем цикл оператором break.

6. После завершения цикла – досрочного по break или «штатного», когда завершен перебор всех символов строки, а знак препинания в ней не найден, нам надо разделить эти два случая. Для этого мы используем «флаговую» функцию переменной k:

– если k не равно нулю, значит, знак препинания найден и его номер позиции в строке записан в k, – тогда мы выполняем операцию «удаления» этого k-го символа из строки (п. 7);

– иначе, если k = 0, это означает, что знак препинания найден не был, цикл завершился сам по себе, а значение k сохранилось исходное, которое мы присвоили этой переменной еще до цикла, – тогда мы просто должны вывести сообщение, что знаков препинания в строке нет.

7. Чтобы «удалить» найденный знак препинания, сделаем следующее. Оставляя исходную строку неизменной, будем формировать из нее новую строку. Сначала запишем в нее все символы исходной строки с первого до k-го (не включая его), а затем допишем (конкатенируем) к ней символы из правой части исходной строки от k-го (опять же не включая его) до последнего. Первую часть строки (слева от знака препинания) можно получить, используя функцию LeftStr(st, k-1), а вторую (правую) – используя функцию RightStr(st, dl-k). При этом вычисление количеств извлекаемых символов достаточно очевидно, если представить строку наглядно, как на рис. 2.





Решение достаточно простое. Но запись условного оператора получается довольно громоздкой: ведь в нем надо перебрать (через or) все возможные случаи равенства очередного символа какому-нибудь знаку препинания. Кроме того, подумайте, что было бы, если бы таких сравнений требовалось несколько в разных местах программы и вдруг выяснилось бы, что надо изменить (скажем, дополнить знаком двоеточия) перечень обрабатываемых знаков препинания? Пришлось бы внимательно (но все равно с риском где-то что-то пропустить) просматривать всю программу, выискивать в ней все такие операторы сравнения и дописывать в них еще одно логическое условие…

Можно ли упростить программу, а заодно – и возможные модификации перечня знаков препинания, обрабатываемых в ней? Можно! И в этом нам поможет интересный, но, к сожалению, редко используемый множественный тип данных – множество (простите за получившийся каламбур).


Множество – это набор однотипных элементов. Однако в отличие от массива, в котором такие элементы располагаются последовательно и пронумерованы индексами, множество – это просто группа элементов, «сваленных в одну кучу». Индексов у элементов множества нет. Более того – для множества порядок записи в нем элементов не важен, например [1, 2, 3] и [3, 2, 1] – это одно и то же множество цифр. Другая особенность множества – это уникальность его элементов: каждый из них должен присутствовать в множестве только «в одном экземпляре», без повторов, – например, набор [1, 2, 3, 2, 1] множеством не является.

В языке Паскаль множества определяются следующим образом:





То есть, сначала объявляется некий «класс» множеств, скажем, множество символов или чисел, а затем создается сколько угодно конкретных множеств этого типа. Например:





А после определения типового множества при объявлении экземпляра можно задать требуемые значения элементов, например:





Множество может оставаться и пустым (не содержать никаких элементов), тогда оно обозначается как [].


Над множествами можно выполнять следующие операции:

– объединение (операция + ) – результатом является множество, включающее (по одному разу!) элементы, которые есть хотя бы в одном из исходных множеств;

– пересечение (операция * ) – результатом является множество, включающее только элементы, которые есть в каждом из исходных множеств;

– разность (операция ) – результатом для двух исходных множеств является множество, включающее только элементы, которые есть в первом из этих множеств, но отсутствуют во втором;

– проверка вхождения элемента в множество (операция in) – если данный элемент (левый операнд) входит в заданное множество (правый операнд), то возвращается результат True (логический тип boolean), иначе – результат False;

– добавление элемента в множество – операция типа M := M + [<элемент>] (где М – множество) либо процедура include(<множество>,<элемент>);

– исключение элемента из множества – операция типа M := M – [<элемент>] (где М – множество) либо процедура exclude(<множество>,<элемент>);


А теперь давайте посмотрим, как можно ту же самую задачу с удалением из строки перового знака препинания решить, используя множества.





Строки листинга, которых не было в предыдущем варианте решения, или которые были изменены по сравнению с ним, выделены жирным шрифтом и синим цветом.

Вначале мы определяем типовое множество znak как множество всех возможных символов.

Затем, в разделе var, мы объявляем экземпляр такого множества – zn – и заносим в него элементы, которые представляют собой символы всех возможных знаков препинания.

Наконец, в операторе if (в цикле перебора символов заданной текстовой строки) нам достаточно записать проверку вхождения очередного символа в заданное нами множество знаков препинания: if st[i] in zn then … А далее обработка найденного знака препинания производится так же, как и в предыдущей программе. Впрочем, можно взамен записать и соответствующую процедуру – это будет короче:





Только в этом случае придется отказаться от формирования новой строки st1 и вместо этого изменять исходную строку st (соответственно, надо записать именно ее и в «итоговом» операторе вывода полученной строки на экран).


Ну как? Очевидно, что запись условного оператора, проверяющего, является ли очередной символ знаком препинания, стала гораздо компактнее и проще?

Но это – только один из получаемых нами благодаря использованию множества «плюсов». Если теперь нам надо дополнить список обрабатываемых знаков препинания двоеточием, то достаточно во всей программе (сколько бы в ней ни было проверок на соответствие символов одному из знаков препинания) дополнить только одну строку:





Красиво и просто получается, не правда ли?

А мы тем временем рассмотрим другие задачи.

Бесплатный фрагмент закончился.

Бесплатно
99,90 ₽

Начислим

+3

Покупайте книги и получайте бонусы в Литрес, Читай-городе и Буквоеде.

Участвовать в бонусной программе
Возрастное ограничение:
12+
Дата выхода на Литрес:
11 ноября 2020
Дата написания:
2020
Объем:
65 стр. 50 иллюстраций
Правообладатель:
Автор
Формат скачивания:
Текст
Средний рейтинг 4 на основе 1 оценок
По подписке
Аудио
Средний рейтинг 5 на основе 1 оценок
Текст
Средний рейтинг 3,4 на основе 8 оценок
По подписке
Текст
Средний рейтинг 0 на основе 0 оценок
Текст PDF
Средний рейтинг 5 на основе 1 оценок
Текст, доступен аудиоформат
Средний рейтинг 0 на основе 0 оценок
По подписке
Məlikməmmədin nağılı
Народное творчество (Фольклор)
Текст
Средний рейтинг 0 на основе 0 оценок
Текст
Средний рейтинг 0 на основе 0 оценок
По подписке
Текст
Средний рейтинг 5 на основе 1 оценок
По подписке
Текст
Средний рейтинг 0 на основе 0 оценок
По подписке
Текст
Средний рейтинг 5 на основе 2 оценок
По подписке