W jaki sposób usunąć element z listy, ale czy istnieje sposób usunięcia więcej niż jednego elementu z listy? Na przykład,Prolog usuwa wiele elementów z listy
deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.
W jaki sposób usunąć element z listy, ale czy istnieje sposób usunięcia więcej niż jednego elementu z listy? Na przykład,Prolog usuwa wiele elementów z listy
deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.
Aby usunąć wiele elementów, możemy sprawdzić, czy element jest w drugim liście i usunąć go, gdy warunek jest spełniony:
deletelist([], _, []).
deletelist([X|Xs], Y, Z) :- member(X, Y), deletelist(Xs, Y, Z), !.
deletelist([X|Xs], Y, [X|Zs]) :- deletelist(Xs, Y, Zs).
% sorry!
deletelist(Xs,Ys,Zs) :-
findall(A,(
member(A,Xs),
\+(member(A,Ys))),
Zs).
SWI-Prolog oferuje 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(Xs,[],Xs).
deletelist(Xs,[Y|Ys],Zs):-
delete(Xs,Y,As),
deletelist(As,Ys,Zs).
Aby usunąć pojedynczy element z listy, znajduje się funkcja biblioteczna "delete/3", która pobiera listę i element, który chcesz usunąć z tej listy i zwraca nową listę z usuniętym elementem. Wykorzystałem to i zwróciłem ponownie listę przedmiotów, które wymagają usunięcia z listy.
Oto definicja, która zawsze daje poprawne odpowiedzi (rozwiązanie modulo):
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).
Korzystanie tfilter/3
i memberd_truth/3
od innych odpowiedzi. Jeśli Twój Prolog nie obsługuje dif/2
, zobacz bezpieczną aproksymację w iso_dif/2
.
Niektóre z bardziej nietypowych pytań, które wciąż wychodzą poprawne:
?- deletelist([a], [X], Zs).
X = a,
Zs = [] ;
Zs = [a],
dif(X, a) ;
false.
?- deletelist([X], [Y], [X]).
dif(X, Y) ;
false.
A oto niektóre pytania, które faktycznie nie uda (a więc kończą), ale raczej pętla. Pamiętaj, że zapętlenie jest o wiele lepsze niż podanie nieprawidłowej odpowiedzi.
?- deletelist([a], Zs, Zs).
ERROR: Out of global stack
?- deletelist(Xs, Xs, Xs).
Xs = [] ;
ERROR: Out of local stack
Chciałbym umieścić! między członkiem i deleteList. – Vincent
'deletelist ([a], [a], [a])." Udaje się, ale powinno zawieść. – false