プロローグでリスト要素の連続した重複を排除する
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
この問題は、リストに沿って1回繰り返すことで解決できます。リストの任意の時点で、現在の要素と次の要素をチェックします。それらが同じである場合は現在の要素を無視し、異なる場合は現在の要素を取得します。
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).
1番目と2番目の句は、重複する要素がない基本句です。3番目と4番目の句は再帰的なルールです。
3番目の節では、入力リストに2つの値がX1
ありX2
、それらが異なるdif(X1, X2)
場合は、現在の値を保持することを示します。
4番目の節では、同じ連続する値がある場合、現在の値を無視します。
3番目と4番目の句は相互に排他的であるため、述語を決定論的にするには、次のように組み合わせる方がよいでしょう。
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).