2016-06-02 4 views
-1

ich, ob Array B überprüfen wollen, ist Permutation von Array A.Überprüfen Sie, ob ein Array eine permutierte Version eines anderen Array ist

Ich dachte, es 1 verwendet getan werden kann for -loop, aber ich verschiedene Quellen sah, dass die meisten von ihnen hat mir gesagt, dass ich 2 for -loops verwenden soll.

for (int i = 0; i < A.length; i++) { 
    boolean found = false; 
    for (int j = 0; j < B.length; j++) 
     if (B[j] == A[i]) { 
      found = true; 
      break; 
     } 
     assert(found); 
    } 
    for (int i = 0; i < B.length; i++) { 
     boolean found = false; 
     for (int j = 0; j < A.length; j++) 
      if (A[j] == B[i]) { 
       found = true; 
       break; 
      } 
     assert(found); 
    } 

Ist dies eine korrekte Umsetzung mit 2 for -loops?

Übrigens, warum musste ich 2 for -loops durchführen, wo erste B mit A vergleicht, dann die zweite A mit B?

+5

'O (N * log (N))' Lösung: sortiere beide Arrays aus und überprüfe, ob 'A [i] = B [i]' für alle 'i's –

+0

Die kanonische Methode ist, beide Arrays zu sortieren und dann prüfen, ob die sortierten Arrays gleich sind. In Ihrem Fall prüft das erste Schleifenpaar, ob alle Elemente von A in B sind und das zweite Paar prüft, ob alle Elemente von B in A sind. Sie können das zweite Paar löschen und stattdessen prüfen, ob A und B gleich lang sind. – dhke

+3

Diese Implementierung ist falsch, da doppelte Werte nicht korrekt verarbeitet werden können. Dieser Code "sagt", dass "A = {1, 2}" und "B = {1, 1, 1, 2}" in Ordnung sind, obwohl es nicht wahr ist. – Tom

Antwort

2

Ihr Code teilt die Permutation Prüfung in zwei Operationen:

  1. für jedes Element A[i] überprüfen, ob A[i] in B
  2. für jedes Element B[j] Prüfung wird angezeigt, wenn B[j] in A

Wie erscheint notiert von @Tom, funktioniert dies im allgemeinen Fall nicht, da es doppelte Elemente ignoriert.

Es ist auch ineffizient. Der zweite Teil kann weggelassen werden, wenn man vor allem anderen A.length == B.length überprüft, aber der Rest ist immer noch O(n²). Und es ist immer noch falsch, weil es falsch positive Ergebnisse liefert, wenn doppelte Elemente betrachtet werden.

Die --Mehr oder less-- kanonischen Verfahren ist sowohl einfach Art-Arrays und für Gleichheit vergleichen:

Arrays.sort(A); 
Arrays.sort(B); 
assert(Arrays.equals(A, B)); 

Sortierung ist wissen im Allgemeinen O(n ln n), so dass der gesamte Vorgang ist nun effizienter zu sein als Vor. Es macht auch die Dinge viel lesbarer.

+0

Dies hat den Nachteil, dass die Arrays 'A' und' B' zuerst geklont werden müssen, um Nebenwirkungen zu vermeiden (wenn diese Arrays irgendwo anders verwendet werden). Btw ein geeigneter Weg, um das Problem "doppelte Werte" zu beheben ist es, die innere Schleife von "i" (d. H. 'Für (int j = i; j <....; j ++)') zu lassen. Dies wäre nicht mehr "O (n²)". Aber ich stimme immer noch zu, dass das Sortieren der allgemein bessere Ansatz zum Überprüfen jeder Art von Permutation ist (z. B. Array, String, ...). – Tom

+0

@Tom Für was es wert ist, führt die [Referenzimplementierung] (http://www.cplusplus.com/reference/algorithm/is_permutation/) für C++ eine explizite Häufigkeitszählung durch und verlangt einen "O (n²)" Worst Case. – dhke

+0

Also, wenn ich den Wert des Arrays manuell für A und B mit gleicher Länge und alle verschiedenen eingeben, kann ich nur die zweite for-Schleife entfernen? Vielen Dank. – MasAdam

Verwandte Themen