프롤로그로 목록 요소의 연속 중복 제거
Nov 27 2020
원래 문제는 다음을 얻을 수있는 방법을 찾는 것이 었습니다.
remove([a,a,a,b,q,q,q,q,e,e,e]),X)
X = [a,b,q,e]
답변
1 rajashekar Nov 28 2020 at 05:20
목록을 따라 한 번 반복하면이 문제를 해결할 수 있습니다. 목록의 어느 시점에서든 현재 요소와 다음 요소를 확인합니다. 동일한 경우 현재 요소를 무시하고 다른 경우 현재 요소를 사용합니다.
rm_dup([], []).
rm_dup([X], [X]).
rm_dup([X1, X2 | Xs], [X1 | Ys]) :-
dif(X1, X2), rm_dup([X2|Xs], Ys).
rm_dup([X, X | Xs], Ys) :-
rm_dup([X | Xs], Ys).
첫 번째 및 두 번째 절은 중복 요소가없는 기본 절입니다. 세 번째와 네 번째 절은 재귀 규칙입니다.
세 번째 절에서 입력 목록에 두 개의 값이 X1
있고 X2
서로 다른 dif(X1, X2)
경우 현재 값을 유지 한다고 명시합니다 .
네 번째 절에서 동일한 연속 값이 있으면 현재 값을 무시합니다.
세 번째 및 네 번째 절은 상호 배타적이므로 술어를 결정적으로 만들려면 다음과 같이 결합하는 것이 좋습니다.
rm_dup([X], [X]) :- !.
rm_dup([X1, X2 | Xs], Ys) :-
dif(X1, X2) -> (rm_dup([X2 | Xs], Ys1), Ys = [X1 | Ys1]);
rm_dup([X2 | Xs], Ys).
더 좋은 방법은 평등을 조건으로 사용하고 then 및 else 절을 뒤집는 것 입니다.
rm_dup([X], [X]) :- !.
rm_dup([X1, X2 | Xs], Ys) :-
X1 = X2 -> rm_dup([X2 | Xs], Ys);
rm_dup([X2 | Xs], Ys1), Ys = [X1 | Ys1].
a3yko Nov 28 2020 at 03:41
조금 길지만 이것이 해결되었습니다.
delete(_,[],[]).
delete(X,[X|T],R):- delete(X,T,R).
delete(X,[H|T],[H|R]) :- delete(X,T,R).
remove([],[]).
remove([H|T], [H|R]) :-
member(H,T),!,
delete(H,T,R1),
remove(R1,R).
remove([H|T],[H|R]):-
remove(T,R).