Autor |
Beitrag |
galagher
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 21.12.12 17:49
Hallo!
Wie gibt's denn das: Mein Programm verhält sich jeweils anders, wenn ich mit Debug- oder Release-Konfiguration kompiliere!
Ich möchte zwei Strings vergleichen, und es arbeitet mindestens dieser Code hier anders, und zwar bei der Release-Konfiguration definitiv falsch, denn beim Vergleich der Strings "was ist Aas", "Aas ist Fleisch toter Tiere" (nicht lachen, bei diesem Text ist es mir aufgefallen!) wird dann oft 0, also keine Ähnlichkeit, zurückgegeben, dann wieder 18. Bei der Debug-Konfiguration ist der Rückgabewert immer 18.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| function Similar(Str1, Str2: String): Integer; VAR treffer, p1, p2, l1, l2, pt, diff: INTEGER; hstr: STRING; test: ARRAY [1..255] OF BOOLEAN; BEGIN if (Str1 = '') or (Str2 = '') then begin Result := -1; exit; end;
if Pos(' ', Str1) = 0 then Str1 := Str1+' '+Str1[1]; if Pos(' ', Str2) = 0 then Str2 := Str2+' '+Str2[1];
IF Length(Str1) < Length(Str2) THEN BEGIN hstr:= Str2; Str2:= Str1; Str1:= hstr; END; l1:= Length (Str1); l2:= Length (Str2); p1:= 1; p2:= 1; treffer:= 0; diff:= Max (l1, l2) DIV 3 + ABS (l1 - l2); FOR pt:= 1 TO l1 DO test[pt]:= FALSE; REPEAT IF NOT (test[p1]) THEN BEGIN IF (Str1[p1] = Str2[p2]) AND (ABS(p1-p2) <= diff) THEN BEGIN test[p1]:= TRUE; treffer:= Succ(treffer); p1:= Succ(p1); p2:= Succ(p2); IF p1 > l1 THEN p1:= 1; END ELSE BEGIN test[p1]:= FALSE; p1:= Succ(p1); IF p1 > Length(Str1) THEN BEGIN WHILE (p1 > 1) AND NOT(test[p1]) DO p1:= Pred(p1); p2:= Succ(p2) END; END; END ELSE BEGIN p1:= Succ(p1); IF p1 > Length(Str1) THEN BEGIN REPEAT p1:= Pred(p1); UNTIL (p1 = 1) OR test[p1]; p2:= Succ(p2) END; END; UNTIL p2 > Length(Str2); Result := 100 * treffer DIV l1; end; |
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
kkausp
      
Beiträge: 77
Erhaltene Danke: 1
W2K, WIN XP, WIN XPe; WIN7
(D1;D2;D5;) D6 Ent.; D2009 Ent.
|
Verfasst: Fr 21.12.12 18:14
Ich würde mal auf uninitialisierte Variablen tippen.
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 21.12.12 18:28
Die einzige Variable, die in der Hinsicht auffällig ist, ist test, da die aus irgendeinem Grund eine feste Länge hat, aber nur bis l1 befüllt wird. Danach stehen Zufallswerte drin. Es wäre vielleicht sinnvoller das Array komplett zu initialisieren oder nur so lang zu machen wie es sein muss.
// EDIT:
Ich hatte Recht...
Wenn du mal die Bereichsprüfung anschaltest und das Array mit SetLength dynamisch auf die initialisierte Größe, bekommst du einen Fehler bei der Bereichsprüfung.
// EDIT2:
Und zwar hier:
Delphi-Quelltext 1:
| WHILE (p1 > 1) AND NOT(test[p1]) DO |
Zuletzt bearbeitet von jaenicke am Fr 21.12.12 18:34, insgesamt 1-mal bearbeitet
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 21.12.12 18:33
jaenicke hat folgendes geschrieben : | Die einzige Variable, die in der Hinsicht auffällig ist, ist test, da die aus irgendeinem Grund eine feste Länge hat, aber nur bis l1 befüllt wird. Danach stehen Zufallswerte drin. Es wäre vielleicht sinnvoller das Array komplett zu initialisieren oder nur so lang zu machen wie es sein muss.
// EDIT:
Ich hatte Recht...
Wenn du mal die Bereichsprüfung anschaltest und das Array mit SetLength dynamisch auf die initialisierte Größe, bekommst du einen Fehler bei der Bereichsprüfung.  |
Ok, da stehe ich jetzt an.
Kannst du mir einen Tipp geben, was genau ich ändern muss?
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 21.12.12 19:37
galagher hat folgendes geschrieben : | jaenicke hat folgendes geschrieben : | Die einzige Variable, die in der Hinsicht auffällig ist, ist test, da die aus irgendeinem Grund eine feste Länge hat, aber nur bis l1 befüllt wird. Danach stehen Zufallswerte drin. Es wäre vielleicht sinnvoller das Array komplett zu initialisieren oder nur so lang zu machen wie es sein muss.
// EDIT:
Ich hatte Recht...
Wenn du mal die Bereichsprüfung anschaltest und das Array mit SetLength dynamisch auf die initialisierte Größe, bekommst du einen Fehler bei der Bereichsprüfung.  |
Ok, da stehe ich jetzt an.
Kannst du mir einen Tipp geben, was genau ich ändern muss? |
//Edit:
Jetzt habe ich den Effekt auch bei Release:konfiguration!
Wie kann den ein und der selbe Stringvergleich unterschiedliche Ergebnisse liefern? Die Strings sind immer gleich, habe das getestet, sie werden nirgendwo verändert. Manchmal 0, manchmal 18.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
richy-f
Hält's aus hier
Beiträge: 15
Win 7, Win 8
C#,C++,Java,Assembler früher Delphi,Pascal
|
Verfasst: Fr 21.12.12 19:43
Wenn du wirklich wie der Vorredner auf nicht initialisierte Bereiche zugreifst oder außerhalb des Arraybereichs, wundert es eigentlich nicht. Da die Daten dort natürlich nicht immer gleich sind, wären die unterschiedlichen Ergebnisse nicht wirklich verwunderlich.
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 21.12.12 20:17
richy-f hat folgendes geschrieben : | Wenn du wirklich wie der Vorredner auf nicht initialisierte Bereiche zugreifst oder außerhalb des Arraybereichs, wundert es eigentlich nicht. Da die Daten dort natürlich nicht immer gleich sind, wären die unterschiedlichen Ergebnisse nicht wirklich verwunderlich. |
Ich kapiere den Code, ehrlich gesagt, nicht...
Das Komische: Bei allen Tests ausserhalb des Projekts erhalte ich mit den selben Strings immer korrekte Results! Der Vergleich erfolgt doch immer gleich! Wie richte ich also das Array so ein, das es passt?
//Edit:
habe es jetzt so gemacht:
Delphi-Quelltext 1: 2: 3:
| test: ARRAY OF BOOLEAN; BEGIN SetLength(test, Length(Str1)+Length(Str2)); |
Sollte das falsch sein, bitte um Info (und wenn's richtig ist, bitte auch!) 
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
richy-f
Hält's aus hier
Beiträge: 15
Win 7, Win 8
C#,C++,Java,Assembler früher Delphi,Pascal
|
Verfasst: Fr 21.12.12 20:30
ist p1 immer kleiner als 256 ?
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 21.12.12 20:39
Beide Strings, Str1 und Str2, können 256 Zeichen nicht erreichen, aber das gilt nur für das aktuelle Projekt. Der Code sollte schon auch längere Strings vergleichen können.
richy-f hat folgendes geschrieben : | ist p1 immer kleiner als 256 ? |
Wie gesagt, ich durchschaue den Code nicht ganz.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
richy-f
Hält's aus hier
Beiträge: 15
Win 7, Win 8
C#,C++,Java,Assembler früher Delphi,Pascal
|
Verfasst: Fr 21.12.12 20:45
galagher hat folgendes geschrieben : | Beide Strings, Str1 und Str2, können 256 Zeichen nicht erreichen, aber das gilt nur für das aktuelle Projekt. Der Code sollte schon auch längere Strings vergleichen können.
richy-f hat folgendes geschrieben : | ist p1 immer kleiner als 256 ? | Wie gesagt, ich durchschaue den Code nicht ganz. |
Also ich hab ihn ehrlich gesagt, nicht so genau angeschaut.
Aber p1 wird mit 1 initialisiert und zählt hoch über die succ funktion.
Dein Array test ist aufjedenfall fest auf eine Länge von 256 Einträgen fixiert und deine strings können ja größer sein.
Zumindest gehe ich mal davon aus, dass in Delphi die Länge nicht wie aus Urzeiten noch 256 ist.
Dann hättest du aufjedenfall an der Stelle, die jaenicke meinte, einen Zugriff außerhalb der Arraygrenzen.
Solange das nicht zu einer Exception, Absturz etc führt, hast du einfach falsche Werte, welche zu unerwünschten Ergebnissen führen können.
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Fr 21.12.12 21:09
richy-f hat folgendes geschrieben : | Dein Array test ist aufjedenfall fest auf eine Länge von 256 Einträgen fixiert |
Jetzt nicht mehr, das Array ist jetzt dynamisch - siehe oben!
richy-f hat folgendes geschrieben : | Solange das nicht zu einer Exception, Absturz etc führt, hast du einfach falsche Werte, welche zu unerwünschten Ergebnissen führen können. |
Ja, zu einer falschen Bewertung! Wenn 0 bedeutet, dass zwei Strings völlig verschieden sind und 100, dass sie identisch sind, dann muss bei zwei Strings, die beide dasselbe Wort enthalten, Result jedenfalls > 0 sein!
Jetzt mit dynamischem Array scheint es ja zu klappen. Aber ist das Array so, wie ich es gemacht habe, auch richtig?
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
|