Seite 2 von 9
Re: FindMapElement
Verfasst: 19.06.2014 22:40
von Martin66119
Vielen Dank Nic
Kannst du mir noch helfen wie ich folgenden Code zum Laden der zu vergleichenen Listen in deinen code einbauen muss. Es sind Zeichenketten Buchstaben und Ziffern.
Code: Alles auswählen
StandardFile$ = "*\" ; anfänglichen Pfad + Dateiname festlegen
Pattern$ = "Text (*.txt)|*.txt;*.csv|Text (*.csv)|*.pb|Alle Dateien (*.*)|*.*"
Pattern = 0 ; wir verwenden den ersten von drei möglichen Pattern als Standard
Filename1$ = OpenFileRequester("Bitte erste Datei zum Vergleich auswählen", StandardFile$, Pattern$, Pattern)
Ergebnis1 = ReadFile(1,FileName1$)
If Ergebnis1 <> 0
While Eof(1)=0
Zeile.s=ReadString(1)
AddElement(Liste1())
Liste1() = Zeile.s
Wend
CloseFile(1)
EndIf
StandardFile$ = "*\" ; anfänglichen Pfad + Dateiname festlegen
Pattern$ = "Text (*.txt)|*.txt;*.csv|Text (*.csv)|*.pb|Alle Dateien (*.*)|*.*"
Pattern = 0 ; wir verwenden den ersten von drei möglichen Pattern als Standard
Filename2$ = OpenFileRequester("Bitte zweite Datei zum Vergleich auswählen", StandardFile$, Pattern$, Pattern)
Ergebnis2 = ReadFile(1,FileName2$)
If Ergebnis2 <> 0
While Eof(1)=0
Zeile.s=ReadString(1)
AddElement(Liste2())
Liste2() = Zeile.s
Wend
CloseFile(1)
EndIf
Re: FindMapElement
Verfasst: 19.06.2014 22:47
von NicTheQuick
Eigentlich musst du doch kaum was ändern. Das findest du schon selbst raus.

Re: FindMapElement
Verfasst: 19.06.2014 23:10
von Martin66119
Hallo Nic,
habe es mal versucht. Aber es klappt nicht. Es kommt eine Fehlermeldung wegen EnableExplicit
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
ReadFile(1,"D:\PB\ExcelDll\Datei1.csv")
While Eof(1)=0
Zeile.s=ReadString(1)
AddElement(Liste1())
Liste1() = Zeile.s
Wend
CloseFile(1)
ReadFile(1,"D:\PB\ExcelDll\Datei2.csv")
While Eof(1)=0
Zeile.s=ReadString(1)
AddElement(Liste2())
Liste2() = Zeile.s
Wend
CloseFile(1)
StartTime = ElapsedMilliseconds()
diff(liste1(), liste2())
Time =ElapsedMilliseconds() - StartTime
MessageRequester("Titel", Str(Time), #PB_MessageRequester_YesNoCancel)
Re: FindMapElement
Verfasst: 19.06.2014 23:26
von NicTheQuick
Wenn man 'EnableExplicit' benutzt, dann muss man zwangsweise alle seine Variablen, Listen, Arrays, usw. deklarieren, d.h. immer 'Define' oder 'Protected' oder vergleichbares wie 'Global', 'Static', usw. nutzen.
Das heißt einfach 'EnableExplicit' entfernen, dann sollte das auch schon funktionieren. Alternativ einfach das ändern, worüber die Fehlermeldung meckert. Eigentlich ganz einfach.
Aber ansonsten ist der Code auch korrekt.
Re: FindMapElement
Verfasst: 19.06.2014 23:34
von Martin66119
Klappt nicht. Der Code hängt sich auf.
Habe ich was mit der Def der Liste1() und Liste2() falsch
Re: FindMapElement
Verfasst: 20.06.2014 00:14
von NicTheQuick
Die Fehlerbeschreibung ist jetzt wenig aussagekräftig. Wo hängt sich das Programm auf? Was ist die Fehlermeldung? Was sagt der Debugger?
Ein bisschen mithelfen könntest du schon, damit man dir nicht alles aus der Nase ziehen muss.
Du kannst mir auch gerne die beiden Dateien geben oder zwei Beispieldateien, bei denen das selbe Problem auftritt.
Re: FindMapElement
Verfasst: 20.06.2014 10:28
von Martin66119
Guten Morgen Nic,
vielen Dank!
Ich hatte beim Übertragen der paar Zeilen einen Fehler gemacht. Nun klappts.
Mein Programm: 65ms
Dein Programm 18 ms
Das ist ja viel schneller. Danke. Gibt es in deinem Code noch einen Bereich, der optimierbar ist.
Wo ich mal was versuchen kann.
Re: FindMapElement
Verfasst: 20.06.2014 12:46
von NicTheQuick
Möglicherweise sind die Codes in dem Thread, der von Stargate
verlinkt wurde, nochmal etwas schneller. Ich hatte das damals mit HashMaps gelöst und das war auch sehr schnell.
Warum muss es überhaupt so schnell sein? Was ist das Grundproblem? Du willst ganz viele Dateien einlesen und miteinander vergleichen? Oder willst du viele Dateien mit genau einer anderen vergleichen? Wie lange dauert eigentlich das Einlesen der Datei, wenn sie noch nicht vom System gecached wurde?
Re: FindMapElement
Verfasst: 20.06.2014 21:20
von Martin66119
Hallo Nic,
ich habe nur ein Netbook mit 1,7 Ghz. Also recht langsam. Es sind ca. 40.000 Datensätze pro Liste. Der Vergleich dauert zwar dann nur ca. 400ms. Mich interessiert aber, wie schnell eine optimale Lösung mit PB ist ohne ASM zu zu verwenden.
Grüße
Martin
Re: FindMapElement
Verfasst: 20.06.2014 21:58
von Martin66119
Hallo Nic,
hier dein Code bei dem ich nur das Einlesen zweier Dateien eingebaut habe. Wieso hast du die Liste list1() und list2() nicht mit einem Pointer realisiert, so wie *onlyIn1.String() und *onlyIn2.String() oder geht das nicht?
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 + "'"
;MessageRequester("Information", *onlyIn1()\s, #PB_MessageRequester_Ok)
Next
Debug ""
Debug "Zeilen, die nur in Liste 2 vorhanden sind:"
ForEach *onlyIn2()
;MessageRequester("Information", *onlyIn2()\s, #PB_MessageRequester_Ok)
Debug "'" + *onlyIn2()\s + "'"
Next
Debug ""
EndProcedure
; ----------------------Hauptprogramm-----------------------------------
NewList liste1.s()
NewList liste2.s()
Define zeile.s
Ergebnis1 = ReadFile(1,"D:\PB\ExcelDll\Datei1.csv")
If Ergebnis1 <> 0
While Eof(1)=0
zeile.s=ReadString(1)
AddElement(liste1())
liste1() = Zeile.s
Wend
CloseFile(1)
EndIf
Ergebnis1 = ReadFile(1,"D:\PB\ExcelDll\Datei2.csv")
If Ergebnis1 <> 0
While Eof(1)=0
zeile.s=ReadString(1)
AddElement(liste2())
liste2() = Zeile.s
Wend
CloseFile(1)
EndIf
StartTime =ElapsedMilliseconds()
diff(liste1(), liste2())
Time =ElapsedMilliseconds() - StartTime
MessageRequester("Information", Str(Time), #PB_MessageRequester_Ok)