【发布时间】:2013-10-24 05:56:58
【问题描述】:
我正在尝试编写一个程序,该程序将两个列表作为输入并检查适当的子集。我开始了:
proper([A],[]).
proper([],[A]).
proper([A|T1],[A|T2]) :- proper(T1,T2).
这对于完全相同顺序的输入非常有效。例如:
?- proper([a,b,c],[a,b,c,d]).
Yes
但不适用于以下输入:
?- proper([a,b,c],[b,d,a,c]).
No
浏览该网站后,我发现了这个先前提出的问题:
这导致我这样修改我的代码:
proper([A],[]).
proper([],[A]).
proper([A|T1],[A|T2) :- member(A,T2), proper(T1,T2).
proper([H1|T1], [H2|T2]) :- \+ member(H1, T2).
这适用于子集,但不适用于适当的子集。我认为我的问题是由于我对proper/4的第二个子句如何工作的理解而引起的。非常感谢任何和所有帮助。
编辑:
意识到我正在尝试确定第一个列表是否是第二个列表的真子集并且第二个列表是第一个列表的真子集。清理代码以更精确。
proper([],_).
proper([A|T1],[A|T2) :- member(A,T2), proper(T1,T2).
proper([H1|T1], [H2|T2]) :- \+ member(H1, T2).
【问题讨论】:
-
只需对您的列表进行排序。这是最明智的做法,标准库也是如何处理它的。
-
@Boris 你能告诉我正确子集的标准库谓词吗?
-
@aBathologist 查看 library(ordsets)(例如在 SWI-Prolog 实现中)及其源代码。 “正确”子集没有谓词,但正如您在答案中已经指出的那样,仅查看长度就足够了。
-
@aBathologist 我的观点主要是,当“集合”表示为 Prolog 列表时,处理“集合”概念的唯一明智方法是保持列表排序。列表是嵌套项,只能在一个方向上遍历。
-
@Boris 我明白了!这是一个重要的观点。我只是以为我一直在忽略一个库,或者有一种特殊的方法可以使用 sort 来完成我无法理解的正确子集检查。感谢您的详细说明。