2014-10-09 3 views
1

Я хочу удалить элемент в списке1, когда он равен элементу в списке2. Запрос и ожидаемый результат:Удалить элемент в списке

filter([[1,2,3],[1]] , [[1]] , X). 
X = [[1, 2, 3]] ; 

filter([[1,2,3],[1],[2,3,4],[2]] , [[1],[2]] , X). 
X = [[1, 2, 3],[2,3,4]] ; 

То, что я сделал прямо сейчас:

filter(_,[],_). 
filter([A|B],[A|D],E):- 
    filter(B,D,E). 
filter([A|B],[C|D],[A|E]):- 
    A\=C, 
    filter(B,D,E). 

но это, кажется, не правильно и дает выход так:

11 ?- filter([[1,2,3],[1]],[[1]],X). 
X = [[1, 2, 3]|_G488] ; 

Может ли кто-нибудь помочь? Может быть, я был близок к успеху.

ответ

0

Ваша программа не будет работать правильно, потому что вы удаляете один элемент из второго списка каждый раз. Также ваш базовый регистр (первое предложение) не должен быть непредубежденной переменной (это то, что дает вам |_G488 в вашем выводе.

Вы должны выполнить итерацию по первому списку, фильтрующему элементы, найденные во втором списке, но не удалять элементы второго списка

Например:...

filter([], _, []). 
filter([Item|L1], L2, L3):- 
    (member(Item, L2) -> L4=L3;L3=[Item|L4]), 
    filter(L1, L2, L4). 

Первый Clase является базовым случаем рекурсии Он утверждает, что выход для пустого списка будет пустой список Второе предложение проверяет, найден ли первый элемент списка ввода на второй список. Если он будет найден, он не будет добавлен в результирующий список; иначе он будет добавлен. Затем он рекурсивно называет себя остальной частью списка ввода. Но ни в коем случае он не удаляет элементы из второго списка.

-1

Ну, ленивый способ будет использовать сборки модулей, findall/3 и member/2:

filter(Xs , Ys , Rs) :- 
    findall(X , (member(X,Xs), \+ member(X,Ys)) , Rs) . 

, который говорит, чтобы найти все X таким образом, что X является членом списка Xs и Xs is *not* a member of the list Ys`.

Предполагая, что ваш инструктор хочет, чтобы вы придумали свою собственную реализацию, вы, вероятно, сначала захотите разложите свою проблему. Вам необходимо сделать две вещи:

  • Перейдите по списку, удалив элементы, которые находятся в другом списке.

  • Учитывая, что данный элемент содержится в другом списке.

Оба они просты.Для того, чтобы определить, если элемент содержится в списке, вы могли бы сказать что-то вроде:

contained_in(X , [X|Ys]) :- % if we find the item in the list, 
    ! .       % - we succeed and eliminate any alternatives. 
contained_in(X , [_|Ys]) :- % otherwise, we discard the head of the list, 
    contained_in(X,Ys) .  % - and keep looking by recursing down. 

Фактическая фильтрация довольно просто, тоже:

filter([]  , _ , [] ) . % once the source list is exhausted, we're done. 
filter([X|Xs] , Ys , [X|R]) :- % otherwise... 
    \+ contained_in(X,Ys) ,   % - if the current list item is not contained in the list of items to be removed, 
    ! ,        % - cut off alternatives, 
    filter(Xs , Ys , R) .   % - add the current item to the result list and recurse down. 
    .        % 
filter([_|Xs] , Ys , R) :-  % if the current list item IS contained in the list of items to be removed, 
    filter(Xs , Ys , R)   % - discard it and recurse down. 
    .        % Easy! 
-1

Ваш filter только subtract доступны со многими системами Прологе (я тестировал с B-Prolog, SWI-Prolog и ECLIPSE):

?- subtract([[1,2,3],[1]] , [[1]] , X). 
X = [[1, 2, 3]]. 

?- subtract([[1,2,3],[1],[2,3,4],[2]] , [[1],[2]] , X). 
X = [[1, 2, 3], [2, 3, 4]]. 

Вы можете посмотреть на источники SWI-Prolog или ECLIPSE для деталей реализации.

Смежные вопросы