Seite 1 von 9
FindMapElement
Verfasst: 19.06.2014 12:54
von Martin66119
Guten Tag,
da ich nur 1x im Jahr eine Minianwednung erstelle (brauche auch nichts großes), komme ich eigentlich nicht viel weiter in meinem Wissen. Vor einigen Monaten hatte ich mal die Frage wie kann man in zwei Listen oder Felder möglichst schnell die Unterschiede herausfinden, gestellt. Die Vorschläge habe ich leider nicht ganz verstanden. Deshalb habe ich folgendes gemacht.
Code: Alles auswählen
NewList Liste1.s()
NewMap Datei1.s()
NewMap Datei2.s()
While NextElement(Liste1())
Ergebnis = FindMapElement(Datei2(),Liste1())
If Ergebnis <> 0
DeleteMapElement(Datei2(), Liste1())
FindMapElement(Datei1(),Liste1())
DeleteMapElement(Datei1(), Liste1())
EndIf
Wend
Wenn die Schleife durch ist, sind nur noch die Unterschiede in Datei1() und Datei2() enthalten.
Nun Frage ich mich aber wenn in der Datei2() ein Element 2x vorhanden ist und das gleich 1x in der Liste1() werden die beiden dann duch den DeleteMapElement(Datei2(), Liste1()) in Dastei2() gelöscht?
Grüße
Martin
Re: FindMapElement
Verfasst: 19.06.2014 13:05
von STARGÅTE
Nach diesen Testergebnis nicht:
Code: Alles auswählen
NewMap Test.i()
AddMapElement(Test(), "A", #PB_Map_NoElementCheck)
Test() = 1
AddMapElement(Test(), "B", #PB_Map_NoElementCheck)
Test() = 2
AddMapElement(Test(), "A", #PB_Map_NoElementCheck)
Test() = 3
ForEach Test()
Debug "Test["+MapKey(Test())+"] = "+Str(Test())
Next
DeleteMapElement(Test(), "A")
Debug "---"
ForEach Test()
Debug "Test["+MapKey(Test())+"] = "+Str(Test())
Next
Durch DeleteMapElement() wird immer nur genau ein Element gelöscht, wenn der Key mehrfach besetzt ist, dann wird nur das zuletzt hinzugefügte gelöscht.
Re: FindMapElement
Verfasst: 19.06.2014 13:20
von Martin66119
Nun habe ich in der Liste1() folgende Elemente
2,3,4
In der Map Datei1() sind auch die Elemente
2,3,4
und der Map Datei2() die Elemente
4,1,2,3,4,5
Wenn die Schleife durch ist, ist der Unterschied 1 und 5
Code: Alles auswählen
While NextElement(Liste1())
Ergebnis = FindMapElement(Datei2(),Liste1())
If Ergebnis <> 0
DeleteMapElement(Datei2(), Liste1())
FindMapElement(Datei1(),Liste1())
DeleteMapElement(Datei1(), Liste1())
EndIf
Wend
Re: FindMapElement
Verfasst: 19.06.2014 13:43
von Martin66119
Nun hab ichs. Ich muss halt nur die Hilfe richtig lesen. Das richtige Flag bei AddElement und schon ist die 4 da
AddMapElement(Datei1(),Zeile,#PB_Map_NoElementCheck)
Gruß un d Danke für die Hilfe
Re: FindMapElement
Verfasst: 19.06.2014 14:10
von Martin66119
Sorry noch eine Frage hinterher.
Hat jemand ggf. einen verwendbaren Code, der schneller ist wie FindMapElement und Delete MapElement.
Grüße
Re: FindMapElement
Verfasst: 19.06.2014 21:31
von matbal
Vielleicht reicht es ja schon, die Map mit mehr Slots zu erstellen. Am schnellsten ist eine Map, wenn sie so viele Slots enthält, wie Elemente hinzugefügt werden sollen.
Die Anzahl der Slots ist immer ein Kompromiß zwischen Speicherverbrauch und Geschwindigkeit.
Re: FindMapElement
Verfasst: 19.06.2014 21:54
von STARGÅTE
Martin66119 hat geschrieben:Hat jemand ggf. einen verwendbaren Code, der schneller ist wie FindMapElement und Delete MapElement.
Soweit ich mich erinnere, wurde dir ja
damals bereichs ein Code gegeben, einfach noch mal ansehen.
Außerdem: "schneller" als was? Wie hast du die Zeit gemessen? Um welche Zeiten geht es?
Re: FindMapElement
Verfasst: 19.06.2014 22:08
von Martin66119
Habe nun bei NewMap Datei1() in die Klammer 20000 eingetragen. Und schon braucht das Programm nur noch 61 ms statt 121 ms.
Danke
Re: FindMapElement
Verfasst: 19.06.2014 22:19
von Martin66119
Der Vergleich besteht aus 11000 x 11000 Zeichenketten. Jeder String ist ca 80 Zeichen lang. In der Liste 1 ist ein String enthalten der in der Liste 2 nicht enthalten ist. In der Liste 2 sind 2 String entahlten, die in Liste 1 nicht sind.
Gemessen mit elapesdMillisecond
Re: FindMapElement
Verfasst: 19.06.2014 22:22
von NicTheQuick
Wenn du tatsächlich nur Listen mit Zahlen oder eindeutig sortierbaren Werten hast, dann geht das ganze auch deutlich schneller, indem man beide Listen sortiert und dann nacheinander durch geht.
Code: Alles auswählen
EnableExplicit
Procedure diff(List list1.s(), List list2.s())
SortList(list1(), #PB_Sort_Ascending)
SortList(list2(), #PB_Sort_Ascending)
Protected NewList *onlyIn1.String()
Protected NewList *onlyIn2.String()
FirstElement(list1())
FirstElement(list2())
Protected next1.i, next2.i
Repeat
; Nur, damit man sieht, was gerade verglichen wird
Debug "Vergleiche '" + list1() + "' - '" + list2() + "'"
next1 = #True
next2 = #True
If (list1() = list2())
; Element ist in beiden Listen, also tue nichts
ElseIf (list1() < list2())
; Element in Liste 1 ist nicht in Liste 2
If AddElement(*onlyIn1())
*onlyIn1() = @list1()
EndIf
next2 = #False
Else
; Element in Liste 2 ist nicht in Liste 1
If AddElement(*onlyIn2())
*onlyIn2() = @list2()
EndIf
next1 = #False
EndIf
If (next1)
If (Not NextElement(list1()))
; Wenn es in Liste 1 nicht mehr weiter geht
While NextElement(list2())
If AddElement(*onlyIn2())
*onlyIn2() = @list2()
EndIf
Wend
Break
EndIf
EndIf
If (next2)
If (Not NextElement(list2()))
; Wenn es in Liste 2 nicht mehr weiter geht
While NextElement(list1())
If AddElement(*onlyIn1())
*onlyIn1() = @list1()
EndIf
Wend
Break
EndIf
EndIf
ForEver
Debug ""
Debug "Zeilen, die nur in Liste 1 vorhanden sind:"
ForEach *onlyIn1()
Debug "'" + *onlyIn1()\s + "'"
Next
Debug ""
Debug "Zeilen, die nur in Liste 2 vorhanden sind:"
ForEach *onlyIn2()
Debug "'" + *onlyIn2()\s + "'"
Next
Debug ""
EndProcedure
NewList liste1.s()
NewList liste2.s()
Define zeile.s
Restore Datei1
Repeat
Read.s zeile
If (AddElement(liste1()))
liste1() = zeile
EndIf
Until zeile = ""
Restore Datei2
Repeat
Read.s zeile
If (AddElement(liste2()))
liste2() = zeile
EndIf
Until zeile = ""
diff(liste1(), liste2())
DataSection
Datei1:
Data.s "Hallo", "das", "ist", "ein", "Test", "!", ""
Datei2:
Data.s "Aber", "Hallo", ",", "das", "Forum", "ist", "ja", "erste", "Sahne", "!", ""
EndDataSection
Achja, und wenn man Geschwindigkeiten messen will, macht man das natürlich ohne Debugger.