簡體   English   中英

Prolog從列表中刪除多個元素

[英]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/3memberd_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM