2017-01-29 14 views
0

Ich schrieb dieses Stück Code, um zu überprüfen, ob eine Liste der Strings vollständig in einem anderen enthalten ist und in diesem Fall die Liste löschen.Überprüfung der Liste der Strings vollständig in anderen Liste der Strings

public static void main(String[] args) { 
    LinkedList<String> l1 = new LinkedList<String>(); 
    LinkedList<String> l2 = new LinkedList<String>(); 
    l1.add("Cc"); 
    l1.add("Dd"); 
    l2.add("Cc"); 
    l2.add("Dd"); 
    l2.add("Ee"); 
    LinkedList<LinkedList<String>> l = new LinkedList<LinkedList<String>>(); 
    l.add(l1); 
    l.add(l2); 
    System.out.println("OUTPUT: " + filterSublist(l)); 

} 

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) { 
    List<LinkedList<String>> uniq = new LinkedList<LinkedList<String>>(l); 
    l.forEach(elem -> uniq.removeIf(x -> !x.equals(elem) && elem.contains(x))); 
    return uniq; 
} 

Die Funktion filterSubList sollte eine Liste der Liste von Strings zurück, die keine Listen hat, die in anderen Listen vollständig enthalten sind. Im Beispiel haben wir:

  • Liste 1: "Cc, Dd"
  • Liste 2: "Cc, Dd, Ee"

Da Liste 1 2 in die Liste vollständig enthalten ist, die Funktion sollte eine Liste von Listen zurück, die nur Liste 2. enthält Aber wenn ich das Programm ausführen ich habe Ausgabe, die eine Liste, die beide enthält:

OUTPUT: [[Cc, Dd], [Cc, Dd, Ee]] 

das ist falsch. Gibt es einen Fehler in der Funktion filterSubList?

+0

Gibt es einen Grund, '' equals() 'Methode nicht zu verwenden, um auf ** Gleichheit ** von zwei' Listen' zu prüfen? –

+0

Ich weiß nicht, ob es einen besseren Weg gibt. Was schlagen Sie vor? –

+0

Nun, Sie könnten die Methode 'equals()' verwenden, die 'true' zurückgibt, wenn die beiden verglichenen Listen gleich sind. Zum Beispiel 'System.out.println (list1.equals (list2))'. Aber beachten Sie, dass die Reihenfolge der Inhalte wichtig ist. Wenn Ihnen die Reihenfolge egal ist, können Sie ein 'HashSet' verwenden. @Walrider –

Antwort

1

Sie suchen nach einer Liste (Objekt), die eine andere Liste (Objekt) enthält. Eine neue Liste wird im Speicher alloted anders werden, wenn ein neues Objekt erstellt wird, sondern für die Objekte nach innen mit containsAll überprüfen:

diese stattdessen versuchen:

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) { 
List<LinkedList<String>> uniq = new LinkedList<LinkedList<String>>(l); 
l.forEach(elem -> uniq.removeIf(x -> !x.equals(elem) && elem.containsAll(x))); 
return uniq; 
} 

Bei Rene einige Punkte, die für die OP angehoben Hier ist eine Implementierung, die auf eine andere Art und Weise seinem Beispiel folgt.

static List<LinkedList<String>> filterSublistAlternate(LinkedList<LinkedList<String>> l) { 
boolean[] removed = new boolean[ l.size() ]; 
outer: for(int i=0; i< l.size() ; i++) 
    inner: for(int j=0; j< l.size() ; j++) 
    { 
     if(i != j) 
     if(l.get(j).containsAll(l.get(i))) 
     { 
      System.out.println(i+" and "+j); 
      if(l.get(i).size() == l.get(j).size()) 
       if(removed[i] == removed[j] && !removed[i]) 
        removed[i] = true; 
       else 
        continue outer; 
      else 
      { 
       removed[i] = true; 
       continue outer; 
      } 

     } 
    } 

for(int i=removed.length-1; i>=0 ; i--) 
    if(removed[i]) 
     l.remove(i); 

return l; 
} 
+0

Diese Lösung hat das Problem, dass "uniq" die gleiche Liste aufgrund der Verwendung von 'equals' möglicherweise mehrfach enthält. –

+0

Equals wird verwendet, damit dieselbe Liste nicht mit sich selbst verglichen wird. – dev8080

+0

Genau wegen 'equals' kann das Ergebnis falsch sein und Duplikate enthalten. Fügen Sie einfach ein weiteres l3 = ["Cc", "Dd", "Ee"] zu l hinzu und schauen Sie sich das Ergebnis an. –

0

schlage ich die Lösung, so wie es ist:

  • mehr Speicher effizient, da es nicht die ursprüngliche Liste dupliziert
  • mehr richtig, wie es wirklich für Teil-Listen überprüft (nicht nur einzelnes Element Existenz)
  • mehr richtig, da es
  • Duplikate aus dem Ergebnis entfernt

Code:

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) { 
    return l.stream() 
     .filter(x -> l.stream().noneMatch(elem -> !elem.equals(x) && Collections.indexOfSubList(elem, x) != -1)) 
     .distinct() 
     .collect(Collectors.toList()); 
} 
+0

"Speicher effizienter, da es die ursprüngliche Liste nicht dupliziert" - meines Wissens war dies eine Voraussetzung - eine separate Liste zurückzugeben.Die anderen können leicht behoben werden. – dev8080

+0

@ dev8080 Die Anforderung wird weiterhin erfüllt, eine Liste wird zurückgegeben. Aber diese Lösung kopiert nicht die vollständige ursprüngliche Liste im Voraus, das ist der Punkt. Wenn also viele Unterlisten entfernt werden, ist die Speicherauslastung geringer. –

Verwandte Themen