这是我第一次尝试使用非样本程序上的列表递归,因为我缺乏经验!
预期的有效查询:
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附加到Result以创建列表元素的交替模式。最后,它将调用mixElements与列表的其余部分L1和L2,以及现在应包含两个列表的第一个头元素的Result列表。
/* Recursive case where both L1 and L2 are not empty */
mixElements([H1|L1],[H2|L2],Result) :- append(H1,H2,Result), mixElements(L1,L2,Result).
我的结果输出总是"没有"。
答案 0 :(得分:3)
在处理列表时,考虑DCG通常是值得的,因为它们产生易于阅读的代码。它进一步有助于为关系选择描述性名称,比如list_list_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]
答案 1 :(得分:0)
基本上有四种情况:
第一个列表为空,第二个列表为空,在这种情况下结果应为空:
mixElements([],[],[]).
第一个列表为空,第二个列表为非空,在这种情况下,结果是第二个列表:
mixElements([],[H2|T2],[H2|T2]).
第一个列表非空,第二个列表为空,在这种情况下,结果是第一个列表:
mixElements([H1|T1],[],[H1|T1]).
finall两个列表都是非空的,在这种情况下,结果的两个第一个元素是列表的头部,然后混合列表的尾部:
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).
我将其作为练习来进一步改进谓词。例如,您可以使用剪切,但这可以消除谓词的多方向,这有时非常有用。
答案 2 :(得分:0)
你正在使用append / 3,而不需要它。当模式由至少一个元素的2个列表组成时,您可以立即获得结果,然后递归以处理尾部:
mixElements([H1|L1],[H2|L2],[H1,H2|Rest]) :-
!, mixElements(L1,L2,Rest).
mixElements(L1,L2,Rest) :- append(L1,L2,Rest).