Algorithmus zum Finden von hinzugefügten / entfernten Elementen in einem Array

8

Ich suche nach dem effizientesten Weg zur Lösung der folgenden

Problem:

%Vor%

Meine bisherige Idee ist:

%Vor%

Kennt jemand eine bessere Lösung, die vielleicht effizienter ist und die ursprünglichen Arrays nicht überschreibt?

    
jj. 04.05.2010, 11:11
quelle

7 Antworten

9

Sortieren ist dein Freund.

Sortieren Sie die zwei Arrays (a und b), und gehen Sie dann (mit x und y als Zähler). Bewege beide um 1 nach unten. Von dort können Sie alle Ihre Tests ableiten:

  • wenn a [x] & lt; b [y], dann wurde a [x] entfernt (und nur inkrement x)
  • wenn ein [x] & gt; b [y], dann wurde b [y] hinzugefügt (und nur y erhöht)

(Ich habe vielleicht einen Randfall übersehen, aber Sie bekommen die allgemeine Idee.)

(Edit: Der Fall der primären Kante, der hier nicht behandelt wird, wird behandelt, wenn Sie das Ende eines der Arrays vor dem anderen erreichen, aber es ist nicht schwer herauszufinden.)

    
Joe 04.05.2010 11:23
quelle
5

Sie könnten auch ein Dictionary<int, int> und einen ähnlichen Algorithmus verwenden:

%Vor%

Im endgültigen Wörterbuch erfahren Sie, welche Elemente (und wie oft) eingefügt / entfernt wurden. Diese Lösung sollte auch für größere Listen ziemlich schnell sein - schneller als das Sortieren.

    
mafu 04.05.2010 11:27
quelle
2

Wenn Ihre Sprache als Multiset verfügbar ist (mit Anzahl von Elementen), ist Ihre Frage eine Standardoperation.

%Vor%

Ergebnis ist A. symdiff (B) (symdiff ist Union minus Schnittpunkt und das ist genau das, was Sie gesucht haben, entfernt und hinzugefügt).

Offensichtlich können Sie auch nur entfernt werden oder nur unter Verwendung des klassischen Unterschieds zwischen den Sätzen hinzugefügt werden.

Es kann trivial mit Hashes implementiert werden und es ist O (n) (Verwendung von Sortierung ist etwas weniger effizient als es O (n.log (n)) wegen der Sortierung selbst).

    
kriss 04.05.2010 11:28
quelle
1

In einer Art C ++ - Pseudocode:

%Vor%     
Andreas Brinck 04.05.2010 11:22
quelle
1

Dies kann in linearer Zeit gelöst werden. Erstellen Sie eine Karte zum Berechnen der Anzahl der Wiederholungen jedes Elements. Gehe durch das before -Array und fülle die Karte. Gehe durch das after -Array und verringere den Wert in der Map für jedes Element. Am Ende, gehen Sie durch die Karte und wenn Sie einen negativen Wert finden, wurde dieses Element hinzugefügt - wenn positiv, wurde das Element entfernt.

Hier ist ein Java-Code dafür (nicht getestet, gerade geschrieben):

%Vor%     
Marko Ciric 23.10.2014 10:59
quelle
0

perl:

%Vor%

Ergebnis:

%Vor%     
Oleg Razgulyaev 04.05.2010 14:16
quelle
0

In Groovy:

%Vor%

Ergebnis:

%Vor%

Für countBy wurde ich von Irgendein groovy magic post

instinct

In groovy inject ist wie reduce in anderen funktionalen Sprachen.

Ich beziehe mich auch auf Groovy Kollektion api Folien von Trygve Amundsen mit wirklich guter Tabelle mit funktionellen Methoden

Zweite Lösung:

%Vor%     
David 01.11.2015 01:01
quelle