Hilangkan duplikat elemen daftar yang berurutan dengan prolog

Nov 27 2020

Masalah aslinya adalah menemukan cara untuk mendapatkan yang berikut ini

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

Jawaban

1 rajashekar Nov 28 2020 at 05:20

Kami dapat menyelesaikan masalah ini dengan satu iterasi di sepanjang daftar. Pada titik mana pun dalam daftar kami memeriksa elemen saat ini dan elemen berikutnya, jika mereka sama maka kami mengabaikan elemen saat ini, jika tidak jika berbeda, kami mengambil elemen saat ini.

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

Klausa pertama dan kedua adalah klausa dasar yang tidak memiliki elemen duplikat. Klausa ketiga dan keempat adalah aturan rekursif.

Dalam klausul ketiga kami menyatakan bahwa jika daftar masukan memiliki dua nilai X1dan X2dan mereka berbeda dif(X1, X2), kemudian menyimpan nilai saat ini.

Pada klausa keempat jika kita memiliki nilai berurutan yang sama maka kita mengabaikan nilai saat ini.

Klausa ketiga dan keempat saling eksklusif sehingga untuk dijadikan predikat deterministik sebaiknya digabungkan sebagai berikut

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

Lebih baik lagi adalah menggunakan kesetaraan sebagai kondisi dan membalik klausa lalu dan lain .

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

Agak panjang, tapi ini menyelesaikannya.

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