Правило Пролога, которое возвращает плоский список и удаляет все дубликаты - PullRequest
0 голосов
/ 14 июля 2020

Я создал код в SWI-Prolog, который удаляет все повторяющиеся элементы и возвращает упорядоченный список. Он может вернуть этот список, но не удаляет дубликаты. Вот что у меня есть на данный момент:

flatten([[]], []).
flatten([], []).
flatten([[H1|H2]|T1], Answer) :-
    flatten([H1|H2], HAnswer),
    flatten(T1, TAnswer),
    append(HAnswer, TAnswer, Answer).

flatten([H|T1], Answer) :-
    flatten(T1, TAnswer),
    append([H], TAnswer, Answer).

Сейчас он выводит это:

[2,4,6,8,1,2,3,4,5,6,7,8]
[v,j,a,v,a,p,y,t,h,o,n]

Когда он должен выводить это:

=> [1,2,3,4,5,6,7,8]
=> [j,v,a,p,y,t,h,o,n]

Что я должен изменить, чтобы эта работа работала? Любая помощь приветствуется.

1 Ответ

0 голосов
/ 15 июля 2020

Насколько я понимаю, вам нужен предикат, который удалит дубликаты и оставит только последнее вхождение.

remove_duplicates([], []).
remove_duplicates([H|T], R) :- member(H, T),!,remove_duplicates(T , R).
remove_duplicates([H|T], [H|R]) :- remove_duplicates(T,R).

Первое предложение - это условие остановки. Второе предложение проверяет, можно ли найти текущий элемент в списке в остальной части списка, если это возможно, оно не добавит его к результату R. В то время как третье, если его нельзя найти в остальной части списка, добавлю к результату. С этим logi c вы сохраняете только последние вхождения.

Самый простой метод:

predicate(L, R):- flatten(L, FL), remove_duplicates(FL, R).

Сначала вы сглаживаете список, а затем применяете предикат удаления дубликатов.

Одно предложение, вы могли бы использовать встроенный предикат atomi c для вашего предиката flatten, это упростило бы его. Это будет выглядеть так:

flatten([],[]).
flatten([H|T], [H|R]):- atomic(H), !, flatten(T,R).
flatten([H|T], R):- flatten(H,R1), flatten(T,R2), append(R1,R2,R).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...