我试图创建一个以两种方式连接两个列表的谓词
test([1,2], [3,4], X)
会给X = [1,3,2,4]
。
我的尝试看起来像那样
test([], [], _).
test([X|L1], [Y|L2], L3) :-
append([X, Y], L3, L4),
test(L1, L2, L4).
问题是,它只提供true.
输出,所以看起来我的列表最后没有存储在L3
var下?我不太确定如何解决这个问题,我会很感激任何提示。
答案 0 :(得分:2)
你所拥有的是一个良好的开端,几乎是功能性的。以下是一些评论。
名称test
非常通用,应该使用更好的名称。从可读性的角度来看,这不仅是一种很好的做法,而且通用名称通常会与预定义的系统谓词冲突。在这种情况下,我会选择interleave
或zip
这两个列表之间的这种关系的通用名称。
您的基本案例test([], [], _)
有效地表明,在两个空列表上运行的结果是您想要的任何列表,这显然不合逻辑。它应该是interleave([], [], []).
在append/3
中使用append([X,Y], L3, L4)
是过度的。您可以简单地写:L4 = [X,Y|L3]
,或者甚至更紧凑:
interleave([X|L1], [Y|L2], [X,Y|L3]) :-
interleave(L1, L2, L3).
使用单个基本案例,您可以将成功解决方案限制为仅包含两个相同长度的列表。如果您希望列出不同长度的列表,您需要一些额外的逻辑来适应。这可以通过两个基本情况来完成。总而言之,你有:
interleave([], L, L). % interleaving the empty list with any list is the same list
interleave([H|T], [], [H|T]). % interleaving any non empty list
% with the empty list is the same list
interleave([X|L1], [Y|L2], [X,Y|L3]) :-
interleave(L1, L2, L3).