如何编写一个prolog程序,将List1和List2作为输入,得到的列表是List1和List2的交替元素?
这是我第一次尝试在一个非示例程序上使用递归,因为我缺乏经验 预期的有效查询:如何编写一个prolog程序,将List1和List2作为输入,得到的列表是List1和List2的交替元素?,list,recursion,prolog,artificial-intelligence,List,Recursion,Prolog,Artificial Intelligence,这是我第一次尝试在一个非示例程序上使用递归,因为我缺乏经验 预期的有效查询: mixElements([],[a,b,c], [a,b,c]). mixElements([a,b],[],[a,b]). mixElements([a,b,c],[d,e,f],[a,d,b,e,c,f]). mixElements([a,b,c],[d,e,f,g,h],[a,d,b,e,c,f,g,h]). 在这里,我试图创建一个基本情况,当输入列表为空时,只返回结果 /* Base cases */ mix
mixElements([],[a,b,c], [a,b,c]).
mixElements([a,b],[],[a,b]).
mixElements([a,b,c],[d,e,f],[a,d,b,e,c,f]).
mixElements([a,b,c],[d,e,f,g,h],[a,d,b,e,c,f,g,h]).
在这里,我试图创建一个基本情况,当输入列表为空时,只返回结果
/* Base cases */
mixElements([],[],Result).
递归语句的逻辑是输入列表必须至少包含1个或多个元素。因此,对于列表1和列表2,它们必须分别用[H | L]表示。然后将H1和H2附加到结果中,以创建列表元素的交替模式。最后,它将使用列表的其余部分L1和L2调用mixElements,结果列表现在应该包含两个列表的第一个头元素
/* Recursive case where both L1 and L2 are not empty */
mixElements([H1|L1],[H2|L2],Result) :- append(H1,H2,Result), mixElements(L1,L2,Result).
我的结果总是“否”。这里基本上有四种情况:
mixElements([],[],[]).
mixElements([],[H2|T2],[H2|T2]).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
mixElements([],[],[]).
mixElements([],[H2|T2],[H2|T2]).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
现在我们创建了一些多余的语句。例如,我们可以将前两条语句合并为一条,如:
mixElements([],L,L).
mixElements([H1|T1],[],[H1|T1]).
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :-
mixElements(T1,T2,TT).
我把它留作进一步改进谓词的练习。例如,您可以使用切割,但这可以消除谓词的多方向性,这有时非常有用。在处理列表时,通常值得考虑DCG,因为它们生成易于阅读的代码。它进一步帮助读者为关系选择一个描述性名称,比如list\u list\u interlocked/3。考虑下面的代码:
list_list_interlocked(L1,L2,I) :-
phrase(interlocked(L1,L2),I).
interlocked([],[]) --> % if both input lists are empty
[]. % the resulting list is also empty
interlocked([],[H2|T2]) --> % if the first input list is empty
[H2], % the head of the second is in the list
interlocked([],T2). % the relation holds for the tail as well
interlocked([H1|T1],[]) --> % if the second input list is empty
[H1], % the head of the first is in the list
interlocked(T1,[]). % the relation holds for the tail as well
interlocked([H1|T1],[H2|T2]) --> % if both lists are non-empty
[H1,H2], % the heads are in the list
interlocked(T1,T2). % the relation holds for the tails as well
您的示例查询将生成所需的结果:
?- list_list_interlocked([],[a,b,c],I).
I = [a,b,c]
?- list_list_interlocked([a,b],[],I).
I = [a,b]
?- list_list_interlocked([a,b,c],[d,e,f],I).
I = [a,d,b,e,c,f]
?- list_list_interlocked([a,b,c],[d,e,f,g,h],I).
I = [a,d,b,e,c,f,g,h]
在不需要的地方使用append/3。当模式由至少一个元素的两个列表组成时,可以立即获得结果,然后递归处理尾部:
mixElements([H1|L1],[H2|L2],[H1,H2|Rest]) :-
!, mixElements(L1,L2,Rest).
mixElements(L1,L2,Rest) :- append(L1,L2,Rest).
提示:
append/3
需要什么类型的元素?@Will:有一个完美的副本!对于mixements(a,B,[a,B])
,a=[a,B],B=[]
和a=[],B=[a,B]
来说,这不是一个潜在的问题吗?