Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Algorithmus zum alphabetischen Sortieren 2er Wörter gesucht


Ballpower - Do 04.01.07 15:47
Titel: Algorithmus zum alphabetischen Sortieren 2er Wörter gesucht
Hallo, ich brauche eine Funktion vom Typ boolean mit den beiden String-Parametern wort1 und wort2, die als Ergebnis true zurückgibt, wenn wort1 alphabetisch vor wort2 kommt, oder die beiden Wörter gleich sind. Wenn wort2 alphabetisch vor wort1 kommt, muss die Funktion false zurückgeben. wort1 und wort2 wird in der Funktion in Kleinbuchstaben mittels AnsiLowerCase() umgewandelt, weil das keine Rolle spielen soll. Ich habe auch schon eine solche Funktion entworfen, doch sie funktioniert nicht wie gewollt, da sie beim Vergleichen des 2. Buchstaben den 1. außer Acht lässt.


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:
function TMain.reihenfolge_richtig(wort1,wort2:String):boolean;
var i:integer;
    kleinwort1,kleinwort2 :String;
begin
     result := true;
     i:=1;
     kleinwort1 := AnsiLowerCase(wort1);
     kleinwort2 := AnsiLowerCase(wort2);
     if kleinwort1 <> kleinwort2 Then
     begin
          while (i <> length(kleinwort1) +1or (i <> length(kleinwort2) +1do
          begin
               if ord(kleinwort1[i]) = ord(kleinwort2[i]) Then
               begin
                    i := i + 1;
               end
               else if ord(kleinwort1[i]) < ord(kleinwort2[i]) Then
               begin
                    result := true;
                    break;
               end
               else if ord(kleinwort1[i]) > ord(kleinwort2[i]) Then
               begin
                    result := false;
                    break;
                    end;
               end;
     end
     else
     begin
          result := true;
     end;

end;


Es wäre nett, wenn mir jemand helfen könnte. Die Lösung braucht nicht schnell, sondern nur einfach zu verstehen zu sein, damit ich als Anfänger da Durchblick finde. Und er sollte wenn möglich mit Delphi 3 funktionieren, damit aus mir kein Raubkopierer wird ;-).

Danke schonmal!


Gausi - Do 04.01.07 15:50

Hallo und :welcome: in der Entwickler-Ecke!
Funktioniert if AnsiLowerCase(wort1) < AnsiLowerCase(wort2) then ... in Delphi3 noch nicht?


Lannes - Do 04.01.07 16:06

Hallo,

oder schau Dir mal CompareText in der Delphi-Hilfe an.
Die Funktion CompareText vergleicht zwei Strings ohne Berücksichtigung der Groß-/Kleinschreibung.


Ballpower - Do 04.01.07 16:17
Titel: if AnsiLowerCase(wort1) < AnsiLowerCase(wort2) then
Doch, es funktoniert schon, aber die gesammte Funktion nicht. Das mit compare Text mache ich sofort. Danke schonmal :-)


Miri - Do 04.01.07 16:24

user profile iconBallpower hat folgendes geschrieben:
Doch, es funktoniert schon, aber die gesammte Funktion nicht.


schätzungsweise nicht richtig gelesen, würd ich mal sagen ;-)

Gausi's Vorschlag ersetzt deine Funktion nahezu komplett, da er gleich die ganzen Worte vergleicht, nicht wie du einzelne Buchstaben! Du brauchst also eigentlich nur die eine if-Bedingung und legst abhängig davon dein Ergebnis fest.


GTA-Place - Do 04.01.07 16:26

Man könnte das vermutlich auch so schreiben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function IsSorted(Word1, Word2: String): Boolean;
var
  X: Integer;
begin
  X := 1;

  Word1 := AnsiLowerCase(Word1);
  Word2 := AnsiLowerCase(Word2);

  while (Word1[X] = Word2[X]) AND (X <= Length(Word1)) AND (X <= Length(Word2)) do
    inc(X);

  Result := Ord(Word1[X]) <= Ord(Word2[X]);
end;

Ungetestet.


Jailbird - Do 04.01.07 16:28

@GTA-Place...Spontan gesagt würde ich erst den Längen-Check machen und erst danach die Buchstaben am Index vergleichen. Aber wahrscheinlich stellt der Optimizer sowas intern sogar um


GTA-Place - Do 04.01.07 16:30

Joa, aber nachdem scheinbar das von Gausi auch funktioniert, hat sich das sowieso erledigt. Aber BTW: Habs getestet, meines würde auch funktionieren ;-)

EDIT: Bei Gausi fehlt aber noch das Gleichheitszeichen:

Delphi-Quelltext
1:
if AnsiLowerCase('Apfel') <= AnsiLowerCase('Apfel'then                    

Er will ja, dass auch True rauskommt, wenn die Wörter gleich sind.


Gausi - Do 04.01.07 16:38

Ob jetzt Apfel vor Apfel kommt, oder Apfel vor Apfel - das ist Jacke wie Hose, würde ich sagen. Wenn man nach dem Test auf richtige Reihenfolge aber eine Vertauschung vornehmen möchte, ist es natürlich sinnvoll zu sagen, dass Apfel Apfel richtig sortiert ist. Sonst bringt man die Obstkiste ja unnötig durcheinander. :D

btw: CompareText macht genau das, was ich gepostet habe - erst ein Lowercase beider Worte (oder wars Uppercase?) und dann den Vergleich.


GTA-Place - Do 04.01.07 16:41
Titel: Re: Algorithmus zum alphabetischen Sortieren 2er Wörter gesucht
user profile iconBallpower hat folgendes geschrieben:
Hallo, ich brauche eine Funktion vom Typ boolean mit den beiden String-Parametern wort1 und wort2, die als Ergebnis true zurückgibt, wenn wort1 alphabetisch vor wort2 kommt, oder die beiden Wörter gleich sind. Wenn wort2 alphabetisch vor wort1 kommt, muss die Funktion false zurückgeben.

user profile iconGausi hat folgendes geschrieben:
Ob jetzt Apfel vor Apfel kommt, oder Apfel vor Apfel - das ist Jacke wie Hose, würde ich sagen.

Ist es nicht - zumindest sieht das Threadersteller anders :mrgreen:

Außerdem hinkt dein Vergleich gewaltig: Jacke kommt nämlich nach Hose und Apfel ist gleich Apfel :mrgreen:.


Ballpower - Do 04.01.07 16:43
Titel: DANKE!
Es war tatsächlich das, was ich brauche, danke. Falls jemand nach mir kommt und ähnliches sucht, hier der Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function TMain.reihenfolge_richtig(wort1,wort2:String):boolean;
begin
result := true;
     if CompareText(wort1,wort2) <= 0 Then
     begin
          result := true;
     end
     else if CompareText(wort1,wort2) > 0 Then
     begin
          result := false;
     end;
end;


Einfacher, als ich es mir ertäumen konnte, danke!


Gausi - Do 04.01.07 16:49
Titel: Re: DANKE!
Eine Kleine Optimierung:


Delphi-Quelltext
1:
2:
3:
4:
function TMain.reihenfolge_richtig(wort1,wort2:String):boolean;
begin
     result := AnsiCompareText(wort1,wort2) <= 0;
end;


Das mit dem Ansi ist bei Umlauten wie ÄÖÜ wichtig.


IngoD7 - Do 04.01.07 16:50

user profile iconGausi hat folgendes geschrieben:
btw: CompareText macht genau das, was ich gepostet habe - erst ein Lowercase beider Worte (oder wars Uppercase?) und dann den Vergleich.

Auch wenn's nicht wirklich wichtig ist, aber wenn ich das richtig durchblicke, vergleicht CompareText Zeichen für Zeichen und subtrahiert dabei jeweils einzelnd 32 vom ASCII-Code, wenn es sich um Kleinbuchstaben handelt.

Aber was vielleicht entscheidender ist:
Wenn schon gleich anfangs von AnsiUpperCase und dergleichen die Rede war, dann sollte man jetzt auch möglichst AnsiCompareText nehmen. :-)

//Nachtrag: Ein Hoch auf die Postingüberschneidungen. ;-)

//2. Nachtrag: Groß- und Kleinbuchstaben verwechselt. Jetzt ist richtig.


Gausi - Do 04.01.07 17:02

Hmm. Irgendwo hab ich mal so ein CompareText-Ding gesehen. Hab grade bei TurboDelphi nochmal reingeguckt - da wars nicht. :gruebel: Da geht das über Funktionen aus der kernel32.dll. Wie MS das implementiert hat, weiß ich allerdings wirklich nicht.

Egal - wieder was gelernt, bzw. ein Irrglaube weniger.