Пролог удалить несколько элементов из списка - PullRequest
5 голосов
/ 23 мая 2011

Я знаю, как удалить элемент из списка, но есть ли способ удалить более одного элемента из списка?Например,

deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.

Ответы [ 5 ]

5 голосов
/ 23 мая 2011

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).
3 голосов
/ 23 мая 2011

Чтобы удалить несколько элементов, мы проверяем, есть ли элемент во втором списке, и удаляем его, когда условие выполняется:

deletelist([], _, []).                  
deletelist([X|Xs], Y, Z) :- member(X, Y), deletelist(Xs, Y, Z), !.
deletelist([X|Xs], Y, [X|Zs]) :- deletelist(Xs, Y, Zs).
1 голос
/ 13 мая 2014

Вот определение, которое всегда дает правильные ответы (по модулю завершения):

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 из других ответов. Если ваш пролог не поддерживает 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
0 голосов
/ 13 мая 2014
deletelist(Xs,[],Xs).
deletelist(Xs,[Y|Ys],Zs):-
    delete(Xs,Y,As),
    deletelist(As,Ys,Zs).

Для удаления одного элемента в списке есть библиотечная функция 'delete / 3', которая берет список и элемент, который вы хотите удалить из этого списка, и возвращает новый список с удаленным элементом.Я использовал это и восстановил список предметов, которые нужно удалить из списка.

0 голосов
/ 23 мая 2011

% sorry!

deletelist(Xs,Ys,Zs) :-
        findall(A,(
                    member(A,Xs),
                    \+(member(A,Ys))),
                Zs).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...