2016-07-02 29 views
1

Vergleich habe ich zwei Listen:eine Liste mit Listen in einer anderen Liste in Prolog

L1 = [[a,b,c], [e,b,d], [f,g,a]] 
L2 = [a,e] 

Ich mag mit jeder Liste in L1 L2 vergleichen und die Anzahl der gemeinsamen Elemente finden. Ich versuche folgenden Code:

common([],L). 
common([H|T], L, Out):-  
    intersection(H,L,Out), common(T, L, Out), 
    length(Out,Len). 

Allerdings ist es nicht funktioniert:

?- common([[a,b,c], [e,b,d], [f,g,a]], [a,e], Outlist). 
false. 

Die Hauptliste bleibt Liste in der Liste (wie nach dem Debuggen mit writeln Aussagen gesehen):

L is: 
[a,e] 
H|T is: 
[[f,g,a]] 
Outlist = [] . 

Wo ist das Problem und wie kann ich das korrigieren?

ich den Code zu debuggen bearbeitet und festgestellt, dass irgendwie hat es begonnen Arbeiten:

common([],L,Out). 
common([H|T], L, Out):-  
    writeln('------------in common--------------'), 
    writeln('L is:'), writeln(L), 
    writeln('H is:'), writeln(H), 
    intersection(L,H,Out2list), 
    writeln('Out2list is:'), writeln(Out2list), 
    common(T, L, Out2). 

41 ?- common([[a,b,c], [e,b,d], [f,g,a]], [a,e], Outlist). 
------------in common-------------- 
L is: 
[a,e] 
H is: 
[a,b,c] 
Out2list is: 
[a] 
------------in common-------------- 
L is: 
[a,e] 
H is: 
[e,b,d] 
Out2list is: 
[e] 
------------in common-------------- 
L is: 
[a,e] 
H is: 
[f,g,a] 
Out2list is: 
[a] 
true. 
+1

Welche Ausgabe erwarten Sie in der "outlist" zu erhalten? – dasblinkenlight

+0

Ich erwarte, dass es [a] zeigt, da es ein gewöhnlicher Gegenstand ist und in einer Kreuzung herauskommen sollte. – rnso

+2

'[[f, g, a]]' ist eine Liste von EINEM ELEMENT, welches '[f, g, a]' 'ist. '[a, e]' ist eine Liste von ZWEI ELEMENTEN, die "a" und "e" sind. Offensichtlich haben diese zwei Listen kein gemeinsames Element, da '{f, g, a]' nicht dasselbe wie entweder 'a' oder 'e' ist. Daher führt "Schnittpunkt ([a, e], [[f, g, a]], R)" zu "R = []". Ihr ursprüngliches Problem besteht also darin, dass Sie * Listen mit Listen * haben, die Sie mit flachen Listen schneiden. '[[f, g, a]]' ist eine Liste von einem Element. '[f, g, a]' ist eine Liste von 3 Elementen. – lurker

Antwort

1

Lassen Sie uns zunächst feststellen, dass Sie ein Prädikat common/2 geschrieben haben und ein Prädikat common/3. Wenn ich Ihre Frage lese, gehe ich davon aus, dass Sie Ersteres als Basis für Common/3 betrachten. Das Nachdenken über die Beziehung Sie beschreiben wollen, wäre es sinnvoll zu definieren, dass der Schnittpunkt der leeren Liste und einer anderen Liste ist die leere Liste:

common([],_,[]). 

Allerdings ist es nicht ganz klar, was Sie die dritte erwarten Argument zu sein. In Ihrer Frage schreiben Sie, dass es die Anzahl der gemeinsamen Elemente sein sollte. Die Verwendung von Länge/2 in Ihrem Prädikat common/3 unterstützt diese Interpretation. In diesem Fall sollten Sie die Längen der jeweiligen Kreuzungen in der dritten Liste haben:

common([],_,[]). 
common([H|T], L, [Len|Out]):- % Len is in the 3rd list 
    intersection(H,L,I),   % I is intersection of H and L 
    length(I,Len),    % Len is length of I 
    common(T, L, Out).   % the same for T, L and Out 

Mit dieser Version Ihres Beispiel Abfrage ergibt:

?- common([[a,b,c], [e,b,d], [f,g,a]],[a,e],I). 
I = [1,1,1] 

In Ihrem ersten Kommentar aber schreiben Sie, dass Sie will Outlist zu [a] sein. Das bedeutet, dass Sie im dritten Argument Listen anstelle von Zahlen verwenden möchten. Aber das Betrachten Ihrer Beispielabfrage [a] kann nicht die Antwort sein. Auf der einen Seite, wenn Sie meinen, dass Sie alle Schnittpunkte der Elemente der ersten Liste mit dem zweiten Argument, um sehen möchten, können Sie so etwas wie schreiben:

common2([],_,[]). 
common2([H|T], L, [I|Out]):- % I is in the third list  
    intersection(H,L,I),  % I is intersection of H and L 
    common2(T, L, Out).   % the same for T, L and Out 

Dies ergibt mit Ihrem Beispiel:

?- common2([[a,b,c], [e,b,d], [f,g,a]],[a,e],I). 
I = [[a],[e],[a]] 

auf der anderen Seite, wenn Sie meinen, dass Sie die Kreuzung von alle die Listen des ersten Arguments mit dem zweiten Argument sehen wollen, können Sie gerne mit so etwas gehen:

common3([],_,[]).    % special case empty list 
common3([H|T],L,I) :-   % if 1st list not empty 
    common3_([H|T],L,I).  % I is described in common3_/3 

common3_([],I,I).    % if the list is empty I = Outlist 
common3_([H|T], L, O) :- 
    intersection(H,L,I),  % I is intersection of H and L 
    common3_(T,I,O).   % only the elements in I can be in O 

Mit Ihrem Beispiel Listen ergibt sich

?- common3([[a,b,c], [e,b,d], [f,g,a]],[a,e],I). 
I = [] 

da weder a noch e in allen drei Listen auftreten.Aber wenn Sie a der zweiten Liste hinzufügen:

?- common3([[a,b,c], [e,b,d,a], [f,g,a]],[a,e],I). 
I = [a] 
+0

Danke für die Erklärung im Detail. – rnso

Verwandte Themen