2013-11-28 9 views
5

Prologda bir listeden yinelenen girdileri kaldırmaya çalışıyorum. Yani bir liste [a, b, a, c, b, a] [a, b, c] döndürecekti. Yerleşik işlevleri kullanamam. Bu kodu araştırdım ve bu kodu buldum.Prolog: Yinelenenleri Kaldırma

member(X,[X|_]) :- !. 
member(X,[_|T]) :- member(X,T). 
set([],[]). 
set([H|T],[H|Out]) :- not(member(H,T)), set(T,Out). 
set([H|T],Out) :- member(H,T), set(T,Out). 

Ama bu [c, b, a] değil listemi alıp dönecekti [a, b, c] Ben bir element ve bir liste alıp bir listesini döndürür kodu kaldırmak zorunda

Listedeki o öğe oluşumları kaldırıldı. Bu yüzden onu kaldırmayı yinelemeli yöntemime dahil etmeye çalıştım, ancak prolog'u çok iyi anlamadım, bu yüzden çalışmıyor. Mantıksal olarak bir liste almak isterim ki, kafanın tüm oluşumları hariç olmak üzere, yeni liste üzerindeki özyinelemeli bir çağrıyla başa çıkmak. Kodun sml'de nasıl görüneceği budur.

fun remv(_,nil) = nil 
| remv(a,x::xs) = if x=a then remv(a,xs) else x::remv(a,xs); 
fun remvdub (nil) = nil 
| remvdub(x::xs) = x::remvdub(remv(x,xs)); 

Yani bu ben Prologun

remv(_,[],[]). 
remv(X,[X|T],Ans) :- remv(X,T,Ans). 
remv(X,[H|T],[H|K]) :- remv(X,T,K). 

remvdub([],[]). 
remvdub([H|T],[H|Ans]) :- remvdub(Ans1,Ans), remv(H,T,Ans1). 

yılında ben eksik çalıştı nedir?

cevap

7
% An empty list is a set. 
set([], []). 

% Put the head in the result, 
% remove all occurrences of the head from the tail, 
% make a set out of that. 
set([H|T], [H|T1]) :- 
    remv(H, T, T2), 
    set(T2, T1). 

% Removing anything from an empty list yields an empty list. 
remv(_, [], []). 

% If the head is the element we want to remove, 
% do not keep the head and 
% remove the element from the tail to get the new list. 
remv(X, [X|T], T1) :- remv(X, T, T1). 

% If the head is NOT the element we want to remove, 
% keep the head and 
% remove the element from the tail to get the new tail. 
remv(X, [H|T], [H|T1]) :- 
    X \= H, 
    remv(X, T, T1). 
+0

Teşekkürler SQB, tam olarak ne yapmaya çalıştığımın mantığı. Kodunuzu incelerken bile, hata yaptığım yeri bulamıyorum, aynı şeyi bana okuyorlar. Yine de seninkilerin ve benimki infinte döngüsünde sıkışıp kalıyor. – user3043403

+0

hmm Bunu düşündüm sanırım, sipariş verin: - benim hattım çok önemli. remvdub ([H | T], [H | Ans]): - remvdub (Ans1, Ans), remv (H, T, Ans1). Remvdub ([H | T], [H | Ans]) olmalıdır: - remv (H, T, Ans1), remvdub (Ans1, Ans). – user3043403

2

Göndermiş olduğunuz Prolog kodunun snippet'i mantıksal olarak doğrudur.

member(X,[X|_]) :- !. 
member(X,[_|T]) :- member(X,T). 
set(A,B) :- set(A, B, []). 
set([],[],_). 
set([H|T],[H|Out],Seen) :- not(member(H,Seen)), set(T,Out, [H|Seen]). 
set([H|T],Out, Seen) :- member(H,Seen), set(T,Out,Seen). 

fikri listesini temsil eden bir üçüncü parametre, eklemektir: Her çoğaltılmış öğenin son, kopya aksine, ilk tutmak istiyorum, aşağıdaki gibi kodunuzu değiştirebilirsiniz Şimdiye kadar gördüğünüz öğeleri ve üyeliği kalan listeye göre kontrol etmek yerine üyeliği kontrol edin. Bu üçüncü bağımsız değişkeni yüklemenizin kullanıcılarından gizlemek için set/2 eklendiğini unutmayın.

Demo on ideone.

+0

Teşekkür dasblinkenlight, bu çalıştı! Merak etmenin dışında, alt kod bloğunda denediğimi yapmanın bir yolu var mı? Kaldırılan kodu, kafa ile ilerleyen daha küçük listeler ve kafanın kopyasını çıkarmak için kullandım mı? – user3043403

+0

@ user3043403 Sml'yi anlamıyorum, bu yüzden çalışan prototip kodunu anlamıyorum. 'Remvdub/2' yükleminin ikinci maddesi, son derece şüpheli görünüyor, çünkü sonsuz tekrarlamaya giriyor gibi görünüyor. – dasblinkenlight