Читайте также:
|
|
Предикат будет иметь два аргумента. Первым аргументом будет данная строка, вторым — список, состоящий из символов исходной строки. Решение будет рекурсивным. Базис: пустой строке будет соответствовать пустой список. Шаг: с помощью встроенного предиката frontchar разобьем строку на первый символ и остаток строки, остаток строки перепишем в список, после чего добавим первый символ исходной строки в этот список в качестве первого элемента.
/* пустой строке соответствует пустой список */str_list("",[]). str_list(S,[H|T]):-/* H — первый символ строки S, S1 — остаток строки */ frontchar(S,H,S1), /* T — список, состоящий из символов, входящих в строку S1*/ str_list(S1,T). Пример 9.4. Подсчет кол-ва вхождений заданного символа в строку
Предикат будет иметь три аргумента: первые два — входные (строка и символ), третий — выходной (количество вхождений второго аргумента в первый).
Решение будет рекурсивным. Рекурсия по строке, в которой ведется подсчет количества вхождений данного символа. Если строка пустая, то не важно, вхождения какого символа мы считаем, все равно ответом будет ноль. Это базис. Шагов рекурсии будет два в зависимости от того, будет ли первым символом строки символ, вхождения которого мы считаем, или нет. В первом случае нужно подсчитать, сколько раз искомый символ встречается в остатке строки, и увеличить полученное число на единицу. Во втором случае (когда первый символ строки отличен от символа, который мы считаем) увеличивать полученное число не нужно. При расщеплении строки на первый символ и хвост нужно воспользоваться уже знакомым нам предикатом frontchar.
char_count("",_,0). /* Любой символ не встречается в пустой строке ни разу*/char_count(S,C,N):-/* символ C оказался первым символом в S, в S1 — оставшиеся символы строки S */ frontchar(S,C,S1),!, /* N1 — количество вхождений символа C в строку S1 */ char_count(S1,C,N1), /* N — количество вхождений символа C в строку S получается */ N is N1+1. char_count(S,C,N):-/* первым символом строки S оказался символ, отличный от исходного символа C *//* в S1 — оставшиеся символы строки S */ frontchar(S,_,S1), /* количество вхождений символа C в строку S совпадает с количеством вхождений символа C в строку S1 */ char_count(S1,C,N).Пример 9.5. Поиск первого вхождения заданного символа в строку.
У предиката будет три параметра. Первые два — входные — символ и строка, третий — выходной — первая позиция вхождения первого параметра во второй параметр или ноль.
Не самая легкая задачка, но мы с ней справимся. Можно, конечно, записать в качестве базиса, что в пустой строке не встречаются никакие символы, но мы пойдем другим путем.
Вначале с помощью предиката frontchar разделим исходную строку на первый символ и остаток строки. Если первым символом строки окажется тот самый символ, позицию которого мы ищем, значит, больше ничего делать не нужно. Ответом будет единица. В этом случае нам даже неважно, какие символы оказались в хвосте строки, поскольку мы ищем первое вхождение данного символа в строку.
В противном случае, если первым символом исходной строки является какой-то символ, отличный от искомого, нам нужно искать позицию вхождения символа в остаток строки. Если искомый символ найдется в хвосте, позиция вхождения символа в исходную строку будет на единицу больше, чем позиция вхождения этого символа в остаток строки. Во всех остальных ситуациях наш символ не встречается в исходной строке и, следовательно, мы должны означить третий аргумент нулем.
str_pos(C,S,1):-/* Искомый символ C оказался первым символом данной строки S */ frontchar(S,C,_),!. str_pos(C,S,N):-/* S1 — состоит из всех символов строки S, кроме первого, который отличается от искомого символа C */ frontchar(S,_,S1), /* N1 — это позиция, в которой символ C встречается первый раз в хвосте S1 или ноль*/ str_pos(C,S1,N1), /* если позиция вхождения символа C в строку S1 не равна нулю, то есть если он встречается в строке S1 */ N1=\=0,!, /* то, увеличив позицию его вхождения на единицу, мы получим позицию его вхождения в исходную строку */ N is N1+1. /* искомый символ не входит в данную строку */str_pos(_,_,0).?- str_pos('2', '1234', X).X = 2Пример 9.6. Замена заданного символа в строке – на другой
У предиката будет четыре параметра. Первые три — входные (исходная строка; символ, вхождения которого нужно заменять; символ, которым нужно заменять первый символ); четвертым — выходным — параметром должен быть результат замены в первом параметре всех вхождений второго параметра на третий параметр.
Решение, как обычно, будет рекурсивным. Если строка пустая, значит, в ней нет символов, и, следовательно, заменять нечего. Результатом будет тоже пустая строка. Если же строка непустая, то мы должны разделить ее с помощью предиката frontchar на первый символ и строку, состоящую из остальных символов исходной строки.
Возможны два варианта. Либо первый символ исходной строки совпадает с тем, который нужно заменять, либо не совпадает.
В первом случае заменим все вхождения первого символа вторым символом в хвосте исходной строки, после чего, опять-таки с помощью предиката frontchar, приклеим полученную строку ко второму символу. В итоге в результирующей строке все вхождения первого символа будут заменены вторым символом. Во втором случае, когда первый символ исходной строки не равен заменяемому символу, заменим в хвосте данной строки все вхождения первого символа на второй, после чего присоединим полученную строку к первому символу первоначальной строки.
/* из пустой строки можно получить только пустую строку */str_replace("",_,_,""):-!. str_replace(S,C,C1,SO):-/* заменяемый символ C оказался первым символом строки S, S1 — остаток от S */ frontchar(S,C,S1),!, /* S2 — результат замены в строке S1 всех вхождений символа C на символ C1 */ str_replace(S1,C,C1,S2), /* SO — результат склейки символа C1 и строки S2 */ frontchar(SO,C1,S2). str_replace(S,C,C1,SO):-/* разделяем исходную строку S на первый символ C2 и строку S2, образованную всеми символами строки S, кроме первого */ frontchar(S,C2,S1), /* S2 — результат замены в строке S1 всех вхождений символа C на символ C1 */ str_replace(S1,C,C1,S2), /* SO — результат соединения символа C1 и строки S2 */ frontchar(SO,C1,S2).Если нам понадобится предикат, который будет заменять не все вхождения первого символа на второй, а только первое вхождение первого символа, то нужно просто из первого правила удалить вызов предиката str_replace(S1,C,C1,S2).
Дата добавления: 2015-09-11; просмотров: 72 | Поможем написать вашу работу | Нарушение авторских прав |