Beseitigen Sie aufeinanderfolgende Duplikate von Listenelementen mit Prolog

Nov 27 2020

Das ursprüngliche Problem bestand darin, einen Weg zu finden, um Folgendes zu erreichen

remove([a,a,a,b,q,q,q,q,e,e,e]),X)
X = [a,b,q,e]

Antworten

1 rajashekar Nov 28 2020 at 05:20

Wir können dieses Problem durch eine Iteration entlang der Liste lösen. An jedem Punkt in der Liste überprüfen wir das aktuelle Element und das nächste Element. Wenn sie gleich sind, ignorieren wir das aktuelle Element. Wenn sie unterschiedlich sind, nehmen wir das aktuelle Element.

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).

Die erste und die zweite Klausel sind Basissätze, in denen keine doppelten Elemente vorhanden sind. Der dritte und vierte Satz sind rekursive Regeln.

In dritter Klausel stellen wir fest, dass , wenn die Eingabeliste zwei Werte hat X1und X2und sie sind anders dif(X1, X2), dann den aktuellen Wert halten.

In der vierten Klausel ignorieren wir den aktuellen Wert, wenn wir dieselben aufeinanderfolgenden Werte haben.

Der dritte und der vierte Satz schließen sich gegenseitig aus. Um das Prädikat deterministisch zu machen, ist es daher besser, sie wie folgt zu kombinieren

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).

Noch besser ist es, nur Gleichheit als Bedingung zu verwenden und die Klauseln then und else umzudrehen.

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

Ein bisschen lang, aber das hat es gelöst.

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).