[英]Prolog remove multiple elements from a list
我知道如何從列表中刪除元素,但有沒有辦法從列表中刪除多個元素? 例如,
deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.
SWI-Prolog提供subtract/3
:
?- subtract([a,b,c,a,b], [a,c], X).
X = [b, b].
?- listing(subtract).
lists:subtract([], _, []) :- !.
lists:subtract([A|C], B, D) :-
memberchk(A, B), !,
subtract(C, B, D).
lists:subtract([A|B], C, [A|D]) :-
subtract(B, C, D).
要刪除多個元素,我們檢查元素是否在第二個列表中,並在條件為真時將其刪除:
deletelist([], _, []).
deletelist([X|Xs], Y, Z) :- member(X, Y), deletelist(Xs, Y, Z), !.
deletelist([X|Xs], Y, [X|Zs]) :- deletelist(Xs, Y, Zs).
這是一個始終產生正確答案的定義(模終止):
deletelist(Xs, Ys, Zs) :-
tfilter(not(list_memberd_truth(Ys)),Xs, Zs).
not(G, E, T) :-
call(G, E, NT),
( NT = true, T = false
; NT = false, T = true
).
list_memberd_truth(Xs, X, Truth) :-
memberd_truth(X, Xs, Truth).
從其他答案中使用tfilter/3
和memberd_truth/3
。 如果您的Prolog不支持dif/2
,請參閱iso_dif/2
以獲得安全的近似值。
一些更不尋常的問題仍然是正確的:
?- deletelist([a], [X], Zs).
X = a,
Zs = [] ;
Zs = [a],
dif(X, a) ;
false.
?- deletelist([X], [Y], [X]).
dif(X, Y) ;
false.
這里有些查詢實際上應該失敗(從而終止),而是循環。 請注意,循環比給出錯誤的答案要好得多。
?- deletelist([a], Zs, Zs).
ERROR: Out of global stack
?- deletelist(Xs, Xs, Xs).
Xs = [] ;
ERROR: Out of local stack
deletelist(Xs,[],Xs).
deletelist(Xs,[Y|Ys],Zs):-
delete(Xs,Y,As),
deletelist(As,Ys,Zs).
要刪除列表中的單個元素,可以使用庫函數“delete / 3”,該函數包含列表和要從該列表中刪除的項目,並返回刪除了該項目的新列表。 我已經使用了這個並且重新審視了需要從列表中刪除的項目列表。
% sorry!
deletelist(Xs,Ys,Zs) :-
findall(A,(
member(A,Xs),
\+(member(A,Ys))),
Zs).
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.