Array / Zahlen vergleichen - Lösungsansatz

  • Hi Leute ich bräuchte man eine schlaue Idee wie ich mein folgendes Problem lösen kann (Pseudo-Code oder Hinweis reicht hoffentlich).


    Ich habe 2 1D Arrays (unterschiedlich groß) jeweils gefüllt mit verschiedenen Zahlen.
    z.B.
    Array1=[10, 20, 20, 100, 100, 100, 100]
    Array2=[20, 20, 100, 100, 50]

    Gesucht werden jetzt alle Zahlen, die in einem Array vorkommen, aber im anderen Array nicht vorhanden sind.

    Im Beispiel wäre das gewünschte Ergebnis: 10, 100, 100, 50
    Zahlen können durchaus mehrfach vorkommen und da im Beispiel die "100" viermal in Array1 und nur zweimal in Array2 vorhanden ist, gehört die "100" zweimal zum gewünschten output.

    Ich hoffe ich habs halbwegs verständlich dargestellt. Also gesucht werden alle Zahlen für die sich kein Paar im anderen Array finden lässt.
    Ich loop hier ohne Plan durch die Arrays und krieg kein vernünftiges Ergebnis raus. :S

    Danke & Gruß


    nuts

    • Offizieller Beitrag

    Hier mal mein Versuch:

  • Wenn ich dich richtig verstanden habe: Alle die in beiden sind entfernen (Je vorkommen 1x), rest zusammenfügen, dann ist das hier, was du haben möchtest:
    Ist etwas Komplexer, müsste aber schneller sein, als das von Oscar ;) (nur bei großen Datenmengen nützlicher)

    Edit: Wenn die beiden Eingabe-Arrays später noch gebraucht werden, sollte das ByRef beim Aufruf rausgenommen werden. Sonst könnte durchaus witziges passieren :P

    MfG Kanashius

  • Das ging ja fix, danke. :)

    Auf Geschwindigkeit kommt es zum Glück nicht wirklich an und daher sind die _Array Schweinereien wohl akzeptabel.
    Eigentlich wollt ich ohne auskommen, aber daran bin ich gescheitert. :D

    eidt\ Ah noch eine Lösung. Werds mir anschauen, danke Kanashius!

  • in Pseudocode tue ich mich schwer, also gleich AutoIt:

    idealerweise sollte immer durch das kleinere Array gelaufen werden

  • @Oscar na, so eine Lösung ist doch aber in besser als |A1| * |A2| (Worst-Case) zu realisieren :)

    Hier mal die Realisierung in n*log n Laufzeit:

    €: Um an solchen Stellen "Array Schweinereien" zu vermeiden hat @AspirinJunkie mal einen super Thread gepostet, in dem er die Implementierung von "alternativen" (sollten eigentlich auch mal AutoIt nativ werden, will z.B. Listen (wie hier genutzt) nicht missen) aufzeigt: Hier zu finden.

    €2: Ich sehe gerade, dass das "gewünschte Ergebnis" unsortiert sein soll. Ist es ein Problem, wenn es sortiert ist? Für unsortiert würde mir auch keine bessere Lösung als das von Oscar einfallen, sofern die Reihenfolge eine Rolle spielt.

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

    Einmal editiert, zuletzt von Xorianator (5. Juli 2016 um 16:01) aus folgendem Grund: Hatte noch nen kleinen Fehler, ist behoben.

    • Offizieller Beitrag

    Wenn es sich um große Arrays handelt und um _ArrayDelete zu umgehen, könnte man auch so vorgehen:

  • Oha jetzt wird hier schon auf Laufzeitverhaltensebene diskutiert. :thumbup:

    Auch wenn ich mal wieder viel zu spät bin mal meine Idee dazu in den Raum geworfen (sollte ein lineares Laufzeitverhalten aufweisen wenn ich mich nicht irre):

  • @AspirinJunkie sehr schöne Idee, auf das Dictionary hätte ich auch kommen können, in dem Beispiel nehmen wir uns aber (meines Blickes nach) nichts. €: Von der Laufzeit der gezählten Schritte her. Aber offensichtlich scheine ich doch zu irren, nach den Messungen. Dass die Operationen wesentlich schneller sind, darüber sei mal hinweg zu sehen.
    In dem Dictionary können wir das suchen in maximal O(log n) realisieren, wenn mich nicht alles täuscht.
    Das führt dazu, dass du mit Zeile 23 |A1| * log(|A2|) und durch Zeile 39 |A2| * log(|A1|) hast, oder irre ich? (Was dann letztendlich dem _ArraySort mit Quicksort gleich kommt))

    €: Hussa! Das nenne ich mal eine Zeit, nicht schlecht, ich ziehe den Hut vor der Geschwindigkeitsverbesserung. Deshalb an der Stelle die Frage: Wie schnell wird in dem Dictionary gesucht? Ich meine eine der schnellsten Datenstrukturen sei der Rot-Schwarz Baum, mit dem wir alles in O(log n) erledigen können.

    Hab mal ne Messung angestellt:

    €: Ich würde auch aufgrund von 8 Elementen und entsprechendem Ergebnis auf logarithmische Laufzeit tippen.

    Spoiler anzeigen

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • Das führt dazu, dass du mit Zeile 23 |A1| * log(|A2|) und durch Zeile 39 |A2| * log(|A1|) hast, oder irre ich? (Was dann letztendlich dem _ArraySort mit Quicksort gleich kommt))

    Ne eigentlich nicht. Ein Dictionary sollte durch die Indexberechnung per Hash für das Suchen in ihr ein Laufzeitverhalten von O(1) haben. Zumindestens in der Theorie. Also komplett unabhängig von der Größe des Dictionaries.

    Hier mal ein kleines Testskript welches Messwerte für Excel raushaut (damit man sich das mal grafisch darstellen kann):

    Komme bei einer linearen Regression darauf auf ein R² von 0.989. Also wirklich lineares Laufzeitverhalten.

  • Ne eigentlich nicht. für das Suchen in ihr ein Laufzeitverhalten von O(1) haben. Zumindestens in der Theorie. Also komplett unabhängig von der Größe des Dictionaries.

    Ha, stimmt, da gabs ja etwas das in O(1) alles findet.
    Wir haben Hashtabellen leider so rudimentär angerissen, dass die mir nicht mal in den Sinn kamen. Ja klar, du hast völlig Recht. Ich sollte mich wohl privat mit Hashtabellen auseinander setzen. Danke dir!

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

    • Offizieller Beitrag

    Es gibt noch eine Möglichkeit und zwar mit Strings.
    Die StringReplace-Funktion ist ja auch recht schnell und so braucht man nur die äußere Schleife:

  • @Oscar bleibt bei |A1| * |A2|

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal