1

我有这两个程序,但它们没有按应有的方式工作。第一个 without_doubles_2(Xs, Ys) 应该表明如果 Ys 是出现在 Xs 中没有重复的元素的列表,则它是真的。Ys 中的元素与 Xs 的顺序相反,保留第一个重复值。例如, without_doubles_2([1,2,3,4,5,6,4,4],X) 打印 X=[6,5,4,3,2,1] 但它打印错误。

without_doubles_2([],[]).
without_doubles_2([H|T],[H|Y]):- member(H,T),!,
                                 delete(H,T,T1),
                                 without_doubles_2(T1,Y).

without_doubles_2([H|T],[H|Y]):-    without_doubles_2(T,Y).

reverse([],[]).
reverse([H|T],Y):- reverse(T,T1), addtoend(H,T1,Y).

addtoend(H,[],[H]).
addtoend(X,[H|T],[H|T1]):-addtoend(X,T,T1).


without_doubles_21(X,Z):-  without_doubles_2(X,Y),
                           reverse(Y,Z).

第二个是如何让这个程序使用字符串?它应该从字符串中删除元音并只打印辅音。

deleteV([H|T],R):-member(H,[a,e,i,o,u]),deleteV(T,R),!.
deleteV([H|T],[H|R]):-deleteV(T,R),!.
deleteV([],[]).
4

2 回答 2

2

您的调用delete总是失败,因为您的参数顺序错误:

delete(+List1, @Elem, -List2)

所以而不是

delete(H, T, T1)

你要

delete(T, H, T1)

使用 swi-prolog 解释器的跟踪功能很容易找到这样的错误 - 只需进入trace.开始跟踪模式,输入谓词,然后查看解释器在做什么。在这种情况下,您会看到失败来自delete语句。可以在此处找到与跟踪相关的文档

另请注意,您可以重写谓词省略成员检查,从而省略第三个子句,因为delete([1,2,3],9001,[1,2,3])计算结果为真 - 如果元素不在列表中,则结果与输入相同。所以你的谓词可能看起来像这样(由于懒惰而缩短了名称):

nodubs([], []).
nodubs([H|T], [H|Y]) :- delete(T, H, T1), nodubs(T1, Y).

对于第二个问题,您可以使用string_to_list谓词将字符串转换为字符列表(表示为 ascii 代码)。

至于从字符串中删除元音的谓词,我会这样实现(对于这个问题可能有更好的解决方案,或者你可以使用一些内置插件,但我的序言有点生疏):

%deleteall(+L, +Elems, -R)
%a helper predicate for deleting all items in Elems from L
deleteall(L, [], L).
deleteall(L, [H|T], R) :- delete(L, H, L1), deleteall(L1, T, R).

deleteV(S, R) :-
    string_to_list(S, L),         %create list L from input string
    string_to_list("aeiou", A),   %create a list of all vovels
    deleteall(L, A, RL),          %use deleteall to delete all vovels from L
    string_to_list(R, RL).        %turn the result back into a string
于 2012-12-17T12:48:56.767 回答
0

deleteV/2 可以使用库(列表):

?- subtract("carlo","aeiou",L), format('~s',[L]).
crl
L = [99, 114, 108].

而要删除重复项,我们可以利用sort /2 并选择/3:

nodup(L, N) :-
    sort(L, S),
    nodup(L, S, N).

nodup([], _S, []).
nodup([X|Xs], S, N) :-
    ( select(X, S, R) -> N = [X|Ys] ; N = Ys, R = S ),
    nodup(Xs, R, Ys).

测试:

?- nodup([1,2,3,4,4,4,5,2,7],L).
L = [1, 2, 3, 4, 5, 7].

编辑得更好,来自 ssBarBee

?- setof(X,member(X,[1,2,2,5,3,2]),L).
L = [1, 2, 3, 5].
于 2012-12-17T13:22:27.000 回答