如何在Prolog中从列表获取唯一无重复元素对?
如何在Prolog中生成列表的唯一二元组合(无重复逆序对)
直接生成唯一对的谓词
你要的my_pairs(X, Y, L)可以通过保证Y出现在X的后续位置来实现,从根源上避免逆序对。核心思路是先定位X,再从X之后的子列表里取Y,而非无约束地遍历整个列表两次。
实现代码:
my_pairs(X, Y, List) :- append(_, [X|Rest], List), % 拆分列表,找到X及X之后的剩余元素Rest member(Y, Rest). % 仅从X之后的元素中选取Y
测试查询效果:
?- my_pairs(X, Y, [a, b, c]). X = a, Y = b ; X = a, Y = c ; X = b, Y = c ; false.
直接得到所有无重复的唯一对,不会出现逆序情况。
另一种等价实现(用select替代append):
my_pairs(X, Y, List) :- select(X, List, Rest), % 从列表中取出X,剩余元素为Rest member(Y, Rest). % 从Rest中选取Y
收集唯一对到列表
如果需要把所有唯一对收集成一个列表,直接用findall配合上面的my_pairs即可:
unique_pairs(List, Result) :- findall([X, Y], my_pairs(X, Y, List), Result).
测试查询效果:
?- unique_pairs([a, b, c], R). R = [[a, b], [a, c], [b, c]].
为什么之前的方法无效?
你之前用两次member加\+ X = Y的方式,会生成所有可能的排列(包括逆序对),因为member会无约束地遍历整个列表两次,X和Y的位置没有先后限制。而list_to_set无法去除逆序对,是因为[a, b]和[b, a]是结构不同的列表,Prolog默认不会将它们视为相同元素。
内容的提问来源于stack exchange,提问作者tomashauser
相关产品推荐
相关产品推荐

