Арифметика и строки
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 выполняет операцию конкатенации строк.
Упражнения
- Найдите двоичное представление натурального числа в виде списка нулей и единиц.
- По двоичному представлению натурального числа в виде списка нулей и единиц найдите его десятичное представление.
- Поменяйте порядок следования слов (токенов) в строке на противоположный.
- Найдите в строке слова-палиндромы.
- Вычислите количество гласных в строке.
- Разбейте строку на подстроки максимальной длины, не превосходящей заданного числа, которые оканчиваются на гласные.
- Отобразите в окне консоли волну (синусоиду).
- Напишите программу, которая переводит
- римские числа в арабские;
- арабские числа в римские.