编写一个删除元音(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]
的成员。虽然我还没到任何地方。
答案 0 :(得分:4)
以下内容基于reification of term equality/inequality。
首先,我们首先定义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].
答案 1 :(得分:1)
这是使用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翻译的错误,或者(更可能)我的错...
答案 2 :(得分:0)
这是代码
deleteV([H|T],R):-member(H,[a,e,i,o,u]),deleteV(T,R),!.
deleteV([H|T],[H|R]):-deleteV(T,R),!.
deleteV([],[]).
它做什么? 首先它是问题本身?它是元音的头部 是的 - >我们忽略它。 不 - >我们需要它。 如果它找到一个空列表,它会构造结果列表,当从回溯返回时,它会在前面附加consonats。 此代码在SWIProlog中进行了测试。