Удалить гласные в списке
Напишите программу, которая удаляет гласные (String
, NoVowelsString
), который удаляет все гласные из данной строки.
Пока у меня есть состояние vowel(X):- member(X,[a,e,i,o,u])
, Затем я подумал о том, что удаляет все элементы из другого списка:
delete2([],L1,L1).
delete2([H|T],L1,L3) :-
delete2(H,L1,R2),
delete2(T,R2,L3).
Таким образом, имея эти два, я подумал, что я могу поставить условие для тех элементов, которые будут удалены, что они должны быть членами [a,e,i,o,u]
, Хотя у меня до сих пор нет нигде.
3 ответа
Вот код
deleteV([H|T],R):-member(H,[a,e,i,o,u]),deleteV(T,R),!.
deleteV([H|T],[H|R]):-deleteV(T,R),!.
deleteV([],[]).
Что оно делает? Сначала это сам вопрос? Это гласная голова Да-> Мы игнорируем это. Нет-> Нам это нужно. Если он находит пустой список, он создает список результатов, и при возврате из обратного отслеживания он добавляет перед собой консонаты. Этот код был протестирован в SWIProlog.
Нижеследующее основано на использовании термина "равенство / неравенство".
Во-первых, мы сначала определяем list_memberd_t/3
, который ведет себя так же, как memberd_truth/3
но имеет другой порядок аргументов:
list_memberd_t([] ,_,false).
list_memberd_t([Y|Ys],X,Truth) :-
if_(X=Y, Truth=true, list_memberd_t(Ys,X,Truth)).
list_memberd_truth(Xs,X,Truth) :- list_memberd_t(Xs,X,Truth).
Для краткости давайте определимся memberd_t/3
основанный на list_memberd_t/3
:
memberd_t(X,Xs,Truth) :- list_memberd_t(Xs,X,Truth).
Как параллель library(apply)
давайте определимся tinclude/3
:
:- meta_predicate tinclude(2,?,?).
tinclude(P_2,Xs,Zs) :-
list_tinclude_list(Xs,P_2,Zs).
list_tinclude_list([], _P_2,[]).
list_tinclude_list([E|Es],P_2,Fs0) :-
if_(call(P_2,E), Fs0 = [E|Fs], Fs0 = Fs),
list_tinclude_list(Es,P_2,Fs).
tfilter/3
это другое имя для tinclude/3
:
tfilter(P_2,As,Bs) :-
tinclude(P_2,As,Bs).
Далее мы определим мета-предикат texclude/3
, противоположно tinclude/3
:
:- meta_predicate texclude(2,?,?).
texclude(P_2,Xs,Zs) :-
list_texclude_list(Xs,P_2,Zs).
list_texclude_list([],_,[]).
list_texclude_list([E|Es],P_2,Fs0) :-
if_(call(P_2,E), Fs0 = Fs, Fs0 = [E|Fs]),
list_texclude_list(Es,P_2,Fs).
Теперь давайте использовать их вместе!
?- texclude(list_memberd_truth([a,e,i,o,u]),
[d,e,l,e,t,e,' ',v,o,w,e,l,s,' ',i,n,' ',a,' ',l,i,s,t], Filtered).
Filtered = [d, l, t, ' ',v, w, l,s,' ', n,' ', ' ',l, s,t].
редактировать
Как альтернатива использованию выше texclude/3
давайте использовать tinclude/3
со вспомогательным предикатом not/3
перевернуть значение истины:
:- meta_predicate not(2,?,?).
not(P_2,X,Truth) :-
call(P_2,X,Truth0),
truth_flipped(Truth0,Truth).
truth_flipped(true,false).
truth_flipped(false,true).
Пример запроса:
?- tinclude(not(list_memberd_truth([a,e,i,o,u])),
[d,e,l,e,t,e,' ',v,o,w,e,l,s,' ',i,n,' ',a,' ',l,i,s,t], Filtered).
Filtered = [d, l, t, ' ',v, w, l,s,' ', n,' ', ' ',l, s,t].
Здесь решение с использованием DCG. Обратите внимание, как получен "выход" (передача аргументов отсутствует, только списки различий)
novowels --> ("a";"e";"i";"o";"u"), !, novowels.
% or ..
% novowels --> [C], {memberchk(C, "aeiou")}, !, novowels.
novowels, [C] --> [C], !, novowels.
novowels --> [].
Я должен признаться, что второй срез мне не нравится, но кажется обязательным.
тестовое задание:
?- phrase(novowels, "abcdefghilmnopq", L),format('~s',[L]).
bcdfghlmnpq
L = [98, 99, 100, 102, 103, 104, 108, 109, 110|...].
Чтокасается второго среза, то, по-видимому, это требуется для записи "левой рукой": если я кодирую с аргументом, без среза, я получаю правильный анализ
novowels(Cs) --> ("a";"e";"i";"o";"u"), !, novowels(Cs).
% novowels(Cs) --> [C], {memberchk(C, "aeiou")}, !, novowels(Cs).
novowels([C|Cs]) --> [C], novowels(Cs).
novowels([]) --> [].
тестовое задание:
?- phrase(novowels(L), "abcdefghilmnopq"),format('~s',[L]).
bcdfghlmnpq
L = [98, 99, 100, 102, 103, 104, 108, 109, 110|...] ;
false.
Интересно, это ошибка переводчика DCG или (более вероятно) моя вина...