Арифметика и строки
10.2. Обработка строк
В языке Visual Prolog имеется класс string, в котором реализовано большое количество предикатов обработки строк.
Следующая программа посвящена поиску токенов наибольшей длины в строке. Длиной строки (string) называется количество символов. Строка разбивается на токены. Находится токен наибольшей длины. В результате следующего преобразования в списке остаются только токены, длина которых совпадает с длиной токена наибольшей длины (используется предикат list::filter/2).
Предикат string::frontToken отделяет первый токен от строки. Предикат toTokens разбивает строку на список токенов. Предикат string::length возвращает длину строки.
open core, console, string class predicates toTokens: (string) -> string*. maxTokens: (string, string* [out], charCount [out]). clauses toTokens(Str) = [Tok | toTokens(RestStr)]:- frontToken(Str, Tok, RestStr), !. toTokens(_) = []. maxTokens(Str, MaxTokList, MaxLen):- TokList = toTokens(Str), TokLenList = list::map(TokList, {(Tok) = length(Tok)}), MaxLen = list::maximum(TokLenList), MaxTokList = list::filter(TokList, {(S):- length(S) = MaxLen}). run():- Str = "И редкий солнца луч, и первые морозы", maxTokens(Str, MaxTokList, Length), write(MaxTokList, "\n", Length), _ = readLine().Пример 10.4. Токены наибольшей длины
В следующей программе текст разбивается на предложения. Знаки препинания ".", "!" и "?" используются в тексте только как знаки конца предложения. Предложение может заканчиваться последовательностью знаков, например, многоточием.
open core, console, string class predicates toSentences: (string) -> string*. getSentence: (string, string, string Sent [out], string [out]). clauses toSentences(Str) = [Sentence | toSentences(RestStr)]:- splitStringBySeparators(Str, ".?!", FirstStr, Sign, Str1), FirstStr1 = trim(FirstStr), FirstStr1 <> "", !, getSentence(Str1, concat(FirstStr1, charToString(Sign)), Sentence, RestStr). toSentences(_) = []. getSentence(Str, Sent, Sentence, Rest):- splitStringBySeparators(Str, ".?!", FirstStr, Sign, RestStr), "" = trim(FirstStr), !, getSentence(RestStr, concat(Sent, charToString(Sign)), Sentence, Rest). getSentence(Str, Sent, Sent, Str). run():- Str = "Зима!.. Крестьянин, торжествуя, " "На дровнях обновляет путь...", L = toSentences(Str), list::forAll(L, {(Sent):- write(Sent), nl}), _ = readLine().Пример 10.5. Разбиение текста на предложения
Предикат splitStringBySeparators находит префикс строки до какого-либо разделителя из символов ".?!", встретившегося в строке первым. Кроме этого, он возвращает сам разделитель, а также остаток строки. Предикат concat выполняет операцию конкатенации строк.
Упражнения
- Найдите двоичное представление натурального числа в виде списка нулей и единиц.
- По двоичному представлению натурального числа в виде списка нулей и единиц найдите его десятичное представление.
- Поменяйте порядок следования слов (токенов) в строке на противоположный.
- Найдите в строке слова-палиндромы.
- Вычислите количество гласных в строке.
- Разбейте строку на подстроки максимальной длины, не превосходящей заданного числа, которые оканчиваются на гласные.
- Отобразите в окне консоли волну (синусоиду).
- Напишите программу, которая переводит
- римские числа в арабские;
- арабские числа в римские.