我试图解决的问题如下:
我得到了一个排序列表,我必须将列表中的第一个和最后一个项目配对。然后我必须将列表中的第 2 个和(最后 1 个)项目配对,直到列表为空或剩余 1 个元素。然后我必须返回一个对的列表。
我决定针对此问题采取的步骤是首先检查列表的长度是否大于 1。如果不是,则意味着我们有一个包含 0 或 1 个元素的列表。
然后,我获取给定列表中的第一个和最后一个项目,从列表中删除它们,将它们配对,然后在新列表上递归调用相同的谓词。一旦我一直下降到 0/1 项,我就会弹出回来并将它们附加到我的返回列表中。
我遇到的问题是,当我尝试将 L = [first,last]
对附加到我的返回列表时,它会出错。下面列出了我的代码。
T
是我的输入列表。
first/2
仅获取列表中的第一项。 pair/3
从 P1
和 P2
中剥离一些信息,然后创建 L = [P1,P2]
。
getMatches(T,K,ReturnList) :-
( length(T,Val),
Val > 1,
first(T,P1),
last(T, P2),
delete(T,P1,G),
delete(G,P2,H),
pair(P1,P2,L),
getMatches(H,K,ReturnList),
append(L,K,ReturnList)
; first(T,_),
K = []
).
使用示例:
如果 T = [1, 2, 3, 4, 5]
则
ReturnList = [[1,5], [2, 4]]
应该成立。
最佳答案
我们定义list_pairs/2
基于常用的列表谓词 append/3
.
list_pairs([] , []). list_pairs([_], []). list_pairs([A,B|Xs0], [A-Z|Yss]) :- append(Xs, [Z], [B|Xs0]), list_pairs(Xs, Yss).
请注意,我们并不代表一对 X
和Y
列表 [X,Y]
,而是作为化合物 X-Y
。这个约定是惯用的、广泛使用的,而且也更有效!
这是 list_pairs/2
的最常见的查询 :
?- list_pairs(Es, Pss). Es = [] , Pss = [] ; Es = [_] , Pss = [] ; Es = [A,B] , Pss = [A-B] ; Es = [A,_,B] , Pss = [A-B] ; Es = [A,B,C,D] , Pss = [A-D,B-C] ; Es = [A,B,_,C,D] , Pss = [A-D,B-C] ; Es = [A,B,C,D,E,F] , Pss = [A-F,B-E,C-D] ; Es = [A,B,C,_,D,E,F] , Pss = [A-F,B-E,C-D] ; Es = [A,B,C,D,E,F,G,H] , Pss = [A-H,B-G,C-F,D-E] ; Es = [A,B,C,D,_,E,F,G,H], Pss = [A-H,B-G,C-F,D-E] ...
关于list - 以递归方式将列表附加到列表列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5207046/