List 序言,删除列表列表中的超集
假设我有以下列表:List 序言,删除列表列表中的超集,list,prolog,subset,superset,List,Prolog,Subset,Superset,假设我有以下列表: List = [[a],[a,b],[a,c],[b,c],[b,d],[a,b,c],[a,b,d],[b,c,e],[b,d,e,f]] 目标是删除列表中作为列表超集的每个列表 包含列表的列表始终具有以下属性: 列表中的列表按长度排序 列表中的每个列表都已排序 我最初的想法是简单地从列表中的第一个列表开始,遍历所有其他列表并删除作为超集的列表。接下来我看第二张单子,诸如此类 删除列表[a]的所有超集后,它应该如下所示: List = [[a],[b,c],[b,d]
List = [[a],[a,b],[a,c],[b,c],[b,d],[a,b,c],[a,b,d],[b,c,e],[b,d,e,f]]
目标是删除列表中作为列表超集的每个列表
包含列表的列表始终具有以下属性:
- 列表中的列表按长度排序
- 列表中的每个列表都已排序
List = [[a],[b,c],[b,d],[b,c,e],[b,d,e,f]]
接下来,应删除[b,c]的超集:
List = [[a],[b,c],[b,d],[b,d,e,f]]
最后是[b,d]的超集:
List = [[a],[b,c],[b,d]]
上面这一行应该是结果
我已经创建了一个类似于成员谓词的谓词,但它不是获取单个元素并将其与列表进行比较,而是获取整个列表并将其与列表进行比较:
memberList([],_).
memberList([X|Xs],Y) :-
member(X,Y),
memberList(Xs,Y).
这只适用于列表
?- memberList(a,[a,b,c]).
false.
?- memberList([a],[a,b,c]).
true .
?- memberList([a,b],[a,b,c]).
true .
但在这之后我有点迷路了
我尝试了以下方法,可以删除单个集合的超集,但不起作用:
removeSupersetsList(_,[],[]).
removeSupersetsList(X,[Y|Ys],[Y|Out]) :-
not(memberList(X,Y)),
removeSupersetsList(X,Ys,Out).
removeSupersetsList(X,[Y|Ys],Out) :-
memberList(X,Y),
removeSupersetsList(X,Ys,Out).
所以我想知道是否有人能给我指出正确的方向,从列表中删除所有超集,或者甚至给出正确的谓词。-Hello Xylon,我想我理解你的想法,所以我尝试用这个想法创建了一个解决方案。在这里(让我知道它是否适合您的需要,或者它是否有bug…) %删除(ToRemove、ListWithPublists、LocRez、FinalRez) %ListWithPublists中的列表将被删除,具体取决于要删除的列表 %LocRez是用于获取最终值的累加器(在末尾)
remove(_,[],LocRez,LocRez) :- !.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
memberList(ToRemove,Sublist),
remove(ToRemove,Rest,LocRez,FinalRez),!.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
not(memberList(ToRemove,Sublist)),
append(LocRez,[Sublist],LocRezNew),
remove(ToRemove,Rest,LocRezNew,FinalRez),!.
removeSupersetsList(List,Rez):-removeSupersetsList(List,[],Rez)%调用此进行测试
remove(_,[],LocRez,LocRez) :- !.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
memberList(ToRemove,Sublist),
remove(ToRemove,Rest,LocRez,FinalRez),!.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
not(memberList(ToRemove,Sublist)),
append(LocRez,[Sublist],LocRezNew),
remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%删除超级设置列表(列表、LocRez、最终版)
remove(_,[],LocRez,LocRez) :- !.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
memberList(ToRemove,Sublist),
remove(ToRemove,Rest,LocRez,FinalRez),!.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
not(memberList(ToRemove,Sublist)),
append(LocRez,[Sublist],LocRezNew),
remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%如果需要,从列表中删除列表头(在此过程中获得Rez)
remove(_,[],LocRez,LocRez) :- !.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
memberList(ToRemove,Sublist),
remove(ToRemove,Rest,LocRez,FinalRez),!.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
not(memberList(ToRemove,Sublist)),
append(LocRez,[Sublist],LocRezNew),
remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%将头部附加到我们的LocRez中(获取LocRezNew),
remove(_,[],LocRez,LocRez) :- !.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
memberList(ToRemove,Sublist),
remove(ToRemove,Rest,LocRez,FinalRez),!.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
not(memberList(ToRemove,Sublist)),
append(LocRez,[Sublist],LocRezNew),
remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%为Rez递归调用此函数
remove(_,[],LocRez,LocRez) :- !.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
memberList(ToRemove,Sublist),
remove(ToRemove,Rest,LocRez,FinalRez),!.
remove(ToRemove,ListWithSublists,LocRez,FinalRez) :- ListWithSublists=[Sublist|Rest],
not(memberList(ToRemove,Sublist)),
append(LocRez,[Sublist],LocRezNew),
remove(ToRemove,Rest,LocRezNew,FinalRez),!.
removeSupersetsList(List,LocRez,LocRez) :- List=[] ,!.
removeSupersetsList(List,LocRez,Final) :- ( List=[ToRemove|_] ; List=[ToRemove] ),
remove(ToRemove,List,[],Rez),
append(LocRez,[ToRemove],LocRezNew),
removeSupersetsList(Rez,LocRezNew,Final),!.
我使用的是SWI Prolog,在那里我找到了一个精心制作的库,然后使用/3可以很容易地清理列表
rem_super_sets([], []).
rem_super_sets([L|Ls], R) :-
( select(T, Ls, L1), % get any T in Ls
ord_subset(L, T) % is T a superset of L ?
-> rem_super_sets([L|L1], R) % discard T, keep L for further tests
; R = [L|L2],
rem_super_sets(Ls, L2)
).
这里有一个验证和结果
test :-
List = [[a],[a,b],[a,c],[b,c],[b,d],[a,b,c],[a,b,d],[b,c,e],[b,d,e,f]],
rem_super_sets(List, R),
write(R).
?- test.
[[a],[b,c],[b,d]]
true.
非常感谢,这正是我们需要的。我们应该更加注意默认谓词,因为这是一个很好的实现。您曾暗示过这一点,但这只适用于按长度排序的集合。非常感谢您的时间和创建的解决方案。