我需要知道如何在不重复的情况下将所有两个列表相互添加,如[1,2]& [3,4]结果将是[1,3] [1,4] [2,3] [2,4]
答案 0 :(得分:0)
这是无法按预期运行的解决方案:
(1) comb([], [], []).
(2) comb([H|T], [X|Y], [H,X]).
(3) comb([H,T|T1], [X,Y|T2], [T,Y]).
(4) comb([H|T], [X|Y], L) :-
comb(T, Y, [H|X]).
(1)说,将空列表与空列表组合是一个空列表。这听起来在逻辑上是正确的。
(2)说, [H,X]
是来自[H|T]
和[X|Y]
的一对元素。这是真的(仅提供解决方案的一种组合)。
(3)说, [T,Y]
是来自[H,T|T1]
和[X,Y|T2]
的一对元素。这也是正确的(仅为解决方案提供另一种组合,与#2不同)。
(4)说, L
是来自[H|T]
和[X|Y]
的一对元素,如果[H|X]
是来自T
的一对元素和Y
。这不可能是真的,因为L
没有出现在子句的结果中,因此它永远不会用值进行实例化。
上述解决方案过度思考,比需要的更复杂。它失败了,因为它硬编码了两个解决方案(匹配前两个元素和后两个元素)。然后recursive子句出错,因为它没有逻辑基础,解决方案留作单例变量。
首先,您需要确定谓词的含义。在这个特定问题中,如果comb(Xs, Ys, P).
是一对(比如P
)[X,Y]
来自X
,您可以认为谓词Xs
为TRUE ( ie ,X
是Xs
)的成员,Y
来自Ys
(Y
是{Ys
的成员1}})。然后,当您查询谓词时,它将提示您每个解决方案,直到找到所有解决方案。
此问题可以通过一条规则说明: [X,Y]
是分别来自Xs
和Ys
的元素的组合,如果X
是成员的话Xs
和Y
的成员是Ys
的成员。这听起来像是一个简单的真实陈述,但是你需要解决这个问题。
将其翻译成Prolog可以得到:
comb(Xs, Ys, [X,Y]) :- % [X,Y] is combination of elements from Xs and Ys if...
member(X, Xs), % X is a member of Xs, and
member(Y, Ys). % Y is a member of Ys
现在让我们试一试:
| ?- comb([1,2],[3,4],P).
P = [1,3] ? ;
P = [1,4] ? ;
P = [2,3] ? ;
P = [2,4]
(2 ms) yes
| ?-
它找到了所有的组合。我们让Prolog完成所有工作,我们只需要声明规则是什么。
如果要在单个列表中收集所有结果,可以使用内置谓词,例如findall/3
:
| ?- findall(P, comb([1,2], [3,4], P), AllP).
AllP = [[1,3],[1,4],[2,3],[2,4]]
yes
| ?-
瞧瞧。 :)
您还可以非常轻松地概括解决方案,并从给定列表列表中的每个列表中选择一个元素。这里,multicomb/2
作为第一个参数列出了列表(例如,[[1,2],[3,4]]`并生成每个元素组合,每个组合一个这些子列表:
multicomb([L|Ls], [X|Xs]) :-
member(X, L),
multicomb(Ls, Xs).
multicomb([], []).
给出了:
| ?- multicomb([[1,2],[3,4]], P).
P = [1,3] ? a
P = [1,4]
P = [2,3]
P = [2,4]
yes
| ?-
和
| ?- multicomb([[1,2],[a,b],[x,y,z]], P).
P = [1,a,x] ? a
P = [1,a,y]
P = [1,a,z]
P = [1,b,x]
P = [1,b,y]
P = [1,b,z]
...