我正在尝试删除Prolog中子列表[z,z,z]之后出现的列表的所有成员。
f.ex removeafterZZZ([a,b,c,z,z,z,a], X) -> X = [a,b,c,z,z,z].
我有方法子列表和加入。
% first argument is a sublist of the second argument
sublist(Sublist, List):-
join(_List1, List2, List),
join(Sublist,_List3, List2).
% we get the list in third argument by joining lists from first two arguments
join([], L, L).
join([Head | Tail1], List2, [Head | Tail3]):-
join(Tail1, List2, Tail3).
所以我一直在考虑3种可能的输入“选项”:
1)[]
2)类似[a,b,c],[a,b,c,z,z],其中输出自动为==输入
3)像[a,b,c,z,z,z,a]
这样的东西所以我想到了3条规则:
removeafterZZZ([],[]). %for empty lists
removeafterZZZ(List,X) := %for lists with no [z,z,z] sublist
not ( sublist ( [z,z,z], List)) ,
X = List.
removeafterZZZ([H|T], X) := %for lists with sublist [z,z,z]
join(H, X, X), %join the head of list with X
removeafterZZZ(T, X). %call function again with tail
所以这显然不会这样,我怎么知道我是否已经将z,z,z写入输出列表?我应该用一个柜台吗?怎么样?
答案 0 :(得分:1)
我认为你需要担心三个案例(所以三条规则......)
[]
[z,z,z]
[z,z,z]
想想如何用传统语言解决这个问题 - 你走到列表中直到它结束,或者你在中间找到[z,z,z]
模式。
答案 1 :(得分:1)
如果允许使用append(它是prolog提供的标准列表谓词),这里是删除后缀的通用方法 -
% removeAfterSuff(Original List, Suffix To Remove, Result)
removeAfterSuff(X, [], X) :- !.
removeAfterSuff(X, Y, X) :- \+ sublist(Y,X).
removeAfterSuff(X, Y, Z) :- append(A, B, X), append(Y, _, B), append(A,Y,Z).
它使用了一个剪切,所以它有点难看,但是否则谓词2会在你传入[]时给出一堆结果(是的,是红色的,无论如何)。
以下是它的工作原理,如果后缀不是列表的成员,则选项2激活,X和Z相等。否则它说“有两个列表,A和B可以创建我的原始列表。第二个列表B,以我的后缀开头,然后包含所有内容(我不在乎那些东西是什么)。因为我知道A是后缀之前的所有内容,然后我的结果是与Y连接的结果。“
请注意,这会为您提供多个结果,例如
[a,b,z,z,z,a,b,z,z,z]
编辑添加:你可以删除第一行,如果你没有可用的空列表返回结果,如
removeAfterSuff([a,b,c], [], Z).
Z = []
Z = [a]
Z = [a,b]
Z = [a,b,c]
答案 2 :(得分:1)
即使是家庭作业,也已经给出了完整的答案......
remove_after([], _, []).
remove_after([H|L], P, O) :-
( append(P, _, [H|L])
-> O = P
; O = [H|O1],
remove_after(L, P, O1) ).