Autor Beitrag
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: 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.
ausblenden volle Höhe Delphi-Quelltext
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:
{http://groups.google.at/group/de.sci.informatik.misc/browse_thread/thread/7e28a09c69fd8b18/37ae33c36782ea32?lnk=st&q=%C3%A4hnlichkeit+zweier+strings+delphi&rnum=6&hl=de#37ae33c36782ea32}
function Similar(Str1, Str2: String): Integer;
VAR treffer, p1, p2, l1, l2, pt, diff: INTEGER;
     hstr: STRING;
    test: ARRAY [1..255OF BOOLEAN;
BEGIN
 if (Str1 = ''or (Str2 = ''then
 begin
  Result := -1;
  exit;
 end;

 {Hinzugefügt: Bei nur 1 Wort das 1. Zeichen des Strings als 2. Wort verwenden}
 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 > 1AND 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 = 1OR 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77
Erhaltene Danke: 1

W2K, WIN XP, WIN XPe; WIN7
(D1;D2;D5;) D6 Ent.; D2009 Ent.
BeitragVerfasst: Fr 21.12.12 18:14 
Ich würde mal auf uninitialisierte Variablen tippen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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. :zwinker:
// EDIT2:
Und zwar hier:
ausblenden Delphi-Quelltext
1:
          WHILE (p1 > 1AND NOT(test[p1]) DO					


Zuletzt bearbeitet von jaenicke am Fr 21.12.12 18:34, insgesamt 1-mal bearbeitet
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 21.12.12 18:33 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
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. :zwinker:

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 21.12.12 19:37 
user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
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. :zwinker:

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! :eyecrazy:
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
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 21.12.12 20:17 
user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
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:

ausblenden 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!) :wink:

_________________
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
BeitragVerfasst: Fr 21.12.12 20:30 
ist p1 immer kleiner als 256 ?
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: 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.
user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
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
BeitragVerfasst: Fr 21.12.12 20:45 
user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
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.
user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 21.12.12 21:09 
user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
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!

user profile iconrichy-f hat folgendes geschrieben Zum zitierten Posting springen:
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!