Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Variablen sortieren (https://www.delphipraxis.net/71554-variablen-sortieren.html)

the_source 16. Jun 2006 22:12


Variablen sortieren
 
Hallo,

bei meinem derzeitigen Programm handelt es sich um ein Kryptoanalyse-tool. Seine Hauptfunktion besteht darin, die Häufigkeit von Buchstaben in einem Text zu zählen und eine Statistik zu erstellen.
In einer Schleife wird bei jeden Buchstaben ein entsprechender Zähler erhöht, bis das Textende erreicht ist. Die die Werte der Zähler (countA, countB....) werden dann ausgegeben, sodass über jeden Buchstaben eine Häufigkeitsinformation vorliegt.
Um ein Diaramm und eine ausführliche Statistik zu erstellen, brauche ich nun die Variable, die den höchsten Wert hat.
Dazu meine Frage: Wie kann ich die höchste Variable bestimmen?


MfG
the_source

Muetze1 16. Jun 2006 22:22

Re: Variablen sortieren
 
Hast du für jeden Buchstaben eine eigene Zählvariable? Dann hast du doch haufenweise Variablen und ein paar zu viele IF Bedingungen - oder nicht? Warum nutzt du kein Array?

Nun noch zu deiner Frage: Schau dir doch einfach mal die Funktion Max() an oder mach es logisch selber: Mit einer IF Bedingung um dem grösser/kleiner Vergleich (> <) kannst du es leicht selber machen...

the_source 16. Jun 2006 22:24

Re: Variablen sortieren
 
Hmm, ja, dann werd ich wohl doch nochmal alles ummodeln. Ich bin zu spät auf die Idee gekommen, ein array zu machen.

Muetze1 16. Jun 2006 22:27

Re: Variablen sortieren
 
Ist aber wirklich ein guter Schritt der sich lohnt, weil sonst schreibst du den Code wirklich für jeden Buchstaben einzelnd. Ein Array macht das ganze recht komformtabel.

Dax 16. Jun 2006 22:41

Re: Variablen sortieren
 
Nein, ein Array macht das ganze erst brauchbar ;)

the_source 17. Jun 2006 10:32

Re: Variablen sortieren
 
hmm, also ich hab mir das jetzt mal zurechtgelget, aber es ergibt sich ein neues Problem.
ich hatte ja vorher ne schleife, in der für jeden Buchstaben eine if-anweisung befand

Delphi-Quellcode:
   for counter:= 1 to laenge do
    begin
     if UpperCase(s[counter]) = 'A' then
      begin
       countA:= countA + 1;
       countDEF:= countDEF + 1;
      end;
     if UpperCase(s[counter]) = 'B' then
      begin
       countB:= countB + 1;
       countDEF:= countDEF + 1;
      end;
und so weite..

jetzt habe ich diese count-Variablen rausgeschmissen und ein Array von 1 bis 26 erstellt.
jetzt habe ich aber das Problem, dass ich ja ne schleife mit möglichst nur einer if-Anweisung möchte.


Delphi-Quellcode:
   for counter:= 1 to laenge do
    begin
     if UpperCase(s[counter]) = 'A' then
      begin
       countArray[1]:= countArray[1] + 1;
       countDEF:= countDEF + 1;
      end;
     if UpperCase(s[counter]) = 'B' then
      begin
       countArray[2]:= countArray[2] + 1;
       countDEF:= countDEF + 1;
      end;
wie bekomm ichs jetzt hin, dass ich, wenn ich für das countArray einen counter einsetze, auch die Buchstaben in eine Art Liste zusammenfasse. Diese müssen ja sonst immer einzeln angegeben werden.

bin grad, während ich das schreibe, auf die Idee gekommen, das mit Ascii-codes zu machen.
Aber es gibt dann noch ein kleines Problem.

Am Ende werden die einzelnen Einträge Labels zugeordnet.

Delphi-Quellcode:
OutA.Caption:= IntToStr(countA);
  OutB.Caption:= IntToStr(countB);
  OutC.Caption:= IntToStr(countC);
Wie kann ich das nun mit den Namen der Labels automatisieren. Ist zwar nicht überlebenswichtig, wäre aber gut.

[edit=Sharky]Code-Tags in Delphi-Tags geändert. Mfg, Sharky[/edit]

Sharky 17. Jun 2006 10:42

Re: Variablen sortieren
 
Hai the_source,

"Herzlich Willkommen in der Delphi-PRAXiS" :hi:

hier mal ein Grundgerüst wie ich da ran gehen würde:
Delphi-Quellcode:
type
  TCounterArray = array [1..255] of Cardinal;


procedure InitCounterArray(var aArray: TCounterArray);
var
  ndx: Integer;
begin
  for ndx := Low(aArray) to High(aArray) do
  begin
    aArray[ndx] := 0;
  end;
end;

procedure CountChars(var aArray: TCounterArray; aValue: string);
var
  ndx: Integer;
begin
  for ndx := 1 to Length(aValue) do
  begin
    aArray[Ord(aValue[ndx])] := aArray[Ord(aValue[ndx])] + 1;
  end;
end;

procedure TDemoForm.btn_testClick(Sender: TObject);
var
  s: string;
  myArray: TCounterArray;
begin
  InitCounterArray(myArray);
  s := 'sdöfljösdlafjpoweiurpowejrsnadöflkasdfsdf';
  CountChars(myArray, s);
end;
In dem Array hast Du jetzt für jeden Buchstaben den Wert wie oft er in dem String s vorkommt. Dieses Array könntest Du jetzt zum Beispiel sortieren.

[edit]aArray als Var-Parameter übergeben

Hawkeye219 17. Jun 2006 10:54

Re: Variablen sortieren
 
@Sharky

Wenn du das Array als var-Parameter übergibst, klappt es besser...

Gruß Hawkeye

Sharky 17. Jun 2006 10:57

Re: Variablen sortieren
 
Zitat:

Zitat von Hawkeye219
... als var-Parameter übergibst, ...

:oops: Wie peinlich :oops:

the_source 17. Jun 2006 11:09

Re: Variablen sortieren
 
hmm, also ich habs jetzt mal provisorisch gemacht mit nen labels, aber das ist nicht das Problem.
Das Problem besteht darin, dass ich am Ende für jeden Buchstaben die Häufigkeit "0" rausbekomme. Der "counterDEF", der die Anzahl aller zulässigen Buchstaben zählt, stimmt.

Ich verstehe einfach nict, woran es liegt.

Delphi-Quellcode:
procedure TForm1.StartClick(Sender: TObject);
 var
  s:String;
  counterMAIN:Integer;
  counterSET:Integer;
  counterCHAR:Integer;
  countDEF:Integer;
  laenge:Integer;
  countArray: Array[1..26] of Integer;
 begin
  for counterSET:= 1 to 26 do
   begin
    countArray[counterSET]:= 0;
   end;
  countDEF:= 0;
  s:= eingabe.Text;
  laenge:= Length(s);
  ProgressBar1.Max:= laenge;
   for counterMAIN:= 1 to laenge do
    begin
     for counterCHAR:= 65 to 90 do
      begin
       if UpperCase(s[counterMAIN]) = CHR(counterCHAR) then
        begin
         countArray[counterCHAR]:= countArray[counterCHAR] + 1;
         countDEF:= countDEF + 1;
        end;
      end;
     ProgressBar1.Position:= ProgressBar1.Position + 1;
    end;
  OutA.Caption:= IntToStr(countArray[1]);
  OutB.Caption:= IntToStr(countArray[2]);
  OutC.Caption:= IntToStr(countArray[3]);
  OutD.Caption:= IntToStr(countArray[4]);
  OutE.Caption:= IntToStr(countArray[5]);
  OutF.Caption:= IntToStr(countArray[6]);
  OutG.Caption:= IntToStr(countArray[7]);
  OutH.Caption:= IntToStr(countArray[8]);
  OutI.Caption:= IntToStr(countArray[9]);
  OutJ.Caption:= IntToStr(countArray[10]);
  OutK.Caption:= IntToStr(countArray[11]);
  OutL.Caption:= IntToStr(countArray[12]);
  OutM.Caption:= IntToStr(countArray[13]);
  OutN.Caption:= IntToStr(countArray[14]);
  OutO.Caption:= IntToStr(countArray[15]);
  OutP.Caption:= IntToStr(countArray[16]);
  OutQ.Caption:= IntToStr(countArray[17]);
  OutR.Caption:= IntToStr(countArray[18]);
  OutS.Caption:= IntToStr(countArray[19]);
  OutT.Caption:= IntToStr(countArray[20]);
  OutU.Caption:= IntToStr(countArray[21]);
  OutV.Caption:= IntToStr(countArray[22]);
  OutW.Caption:= IntToStr(countArray[23]);
  OutX.Caption:= IntToStr(countArray[24]);
  OutY.Caption:= IntToStr(countArray[25]);
  OutZ.Caption:= IntToStr(countArray[26]);
  OutGES.Caption:= IntToStr(countDEF);
 end;
[edit=Sharky]Delphi-Tags gesetzt. Mfg, Sharky[/edit]

Sharky 17. Jun 2006 11:15

Re: Variablen sortieren
 
Hai the_source,

was fällt dir hier auf? ;-)
Code:
var
  countArray: Array[[color=red]1..26[/color]] of Integer;
 begin
.
.

     for counterCHAR:= [color=red]65 to 90[/color] do
         ^^^^^^^^^^^
      begin
       if UpperCase(s[counterMAIN]) = CHR(counterCHAR) then
        begin
         countArray[counterCHAR]:= countArray[counterCHAR] + 1;
                    ^^^^^^^^^^^
.
.

the_source 17. Jun 2006 11:17

Re: Variablen sortieren
 
upps, wie dumm von mir, danke.

o man, wie peinlich .... :oops:

the_source 17. Jun 2006 11:24

Re: Variablen sortieren
 
ah sehr gut, jetzt funktioniert es wunderbar. Jetzt muss ich nur noch wissen, wie ich bei der Label-Zuordung eine Schleife einbauen kann, und wie ich den höchsten eintrag im Array rausbekomme.

Hawkeye219 17. Jun 2006 11:36

Re: Variablen sortieren
 
Hallo the_source,

du kannst dein Programm deutlich vereinfachen, wenn du als Indextyp für das Zählerarray "Char" statt "Integer" wählst:

Delphi-Quellcode:
type
  TCounterArray = array ['A'..'Z'] of Integer; // entweder so (nur Buchstaben)
  TCounterArray = array [Char] of Integer;     // oder so (alle Zeichen)
Das Ansprechen der Arrayelemente sieht dann so aus:

Delphi-Quellcode:
var
  ch : Char;
  Arr : TCounterArray;
begin
  for ch := 'A' to 'Z' do
    Arr[ch] := 0;
  Arr['E'] := 100;
end;
Wenn du diesen Hinweis berücksichtigst, solltest du eigentlich mit einer Schleife auskommen.

Gruß Hawkeye

the_source 19. Jun 2006 12:44

Re: Variablen sortieren
 
hmm, kann mir irgenwer erklären, warum der höchste Wert (wir hier provisorisch uf Label1 ausgeben) falsch ist?

Delphi-Quellcode:
procedure TForm1.StartClick(Sender: TObject);
 var
  s:String;
  counterMAIN:Integer;
  counterSET:Integer;
  counterCHAR:Integer;
  counterCOPY:Integer;
  counterSORT:Integer;
  countDEF:Integer;
  laenge:Integer;
  countArray: Array[65..90] of Integer;
  sortArray: Array[1..26] of Integer;
  unSort:boolean;
  tmp: Integer;
 begin
  for counterSET:= 1 to 26 do
   begin
    countArray[counterSET]:= 0;
   end;
  countDEF:= 0;
  s:= eingabe.Text;
  laenge:= Length(s);
  ProgressBar1.Max:= laenge;
  unSort:= true;
   for counterMAIN:= 1 to laenge do
    begin
     for counterCHAR:= 65 to 90 do
      begin
       if UpperCase(s[counterMAIN]) = CHR(counterCHAR) then
        begin
         countArray[counterCHAR]:= countArray[counterCHAR] + 1;
         countDEF:= countDEF + 1;
        end;
      end;
     ProgressBar1.Position:= ProgressBar1.Position + 1;
    end;
  for counterCOPY:= 1 to 26 do
   begin
    sortArray[counterCOPY]:= countArray[counterSORT + 64];
   end;
  while unSort = true do
   begin
    unSort:= false;
    for counterSORT:= 1 to 26 do
     begin
      if sortArray[counterSORT] < sortArray[counterSORT + 1] then
       begin
        tmp:= sortArray[counterSORT];
        sortArray[counterSORT]:= sortArray[counterSORT + 1];
        sortArray[counterSORT + 1]:= tmp;
        unSort:= true;
       end;
     end;
   end;
  OutA.Caption:= IntToStr(countArray[65]);
  OutB.Caption:= IntToStr(countArray[66]);
  OutC.Caption:= IntToStr(countArray[67]);
  OutD.Caption:= IntToStr(countArray[68]);
  OutE.Caption:= IntToStr(countArray[69]);
  OutF.Caption:= IntToStr(countArray[70]);
  OutG.Caption:= IntToStr(countArray[71]);
  OutH.Caption:= IntToStr(countArray[72]);
  OutI.Caption:= IntToStr(countArray[73]);
  OutJ.Caption:= IntToStr(countArray[74]);
  OutK.Caption:= IntToStr(countArray[75]);
  OutL.Caption:= IntToStr(countArray[76]);
  OutM.Caption:= IntToStr(countArray[77]);
  OutN.Caption:= IntToStr(countArray[78]);
  OutO.Caption:= IntToStr(countArray[79]);
  OutP.Caption:= IntToStr(countArray[80]);
  OutQ.Caption:= IntToStr(countArray[81]);
  OutR.Caption:= IntToStr(countArray[82]);
  OutS.Caption:= IntToStr(countArray[83]);
  OutT.Caption:= IntToStr(countArray[84]);
  OutU.Caption:= IntToStr(countArray[85]);
  OutV.Caption:= IntToStr(countArray[86]);
  OutW.Caption:= IntToStr(countArray[87]);
  OutX.Caption:= IntToStr(countArray[88]);
  OutY.Caption:= IntToStr(countArray[89]);
  OutZ.Caption:= IntToStr(countArray[90]);
  OutGES.Caption:= IntToStr(countDEF);
  Label1.Caption:= IntToStr(sortArray[1]);
 end;

Hawkeye219 19. Jun 2006 13:18

Re: Variablen sortieren
 
Hallo,

Delphi-Quellcode:
var
  countArray: Array[65..90] of Integer; // <-- 65..90
  sortArray: Array[1..26] of Integer;
begin
  for counterSET:= 1 to 26 do           // <-- 1..26 => Crash!
   begin
    countArray[counterSET]:= 0;
   end;
:
    for counterSORT:= 1 to 26 do        // <-- 1..26
     begin
      if sortArray[counterSORT] < sortArray[counterSORT + 1] then // <-- 26 + 1 => Crash!
       begin
        tmp:= sortArray[counterSORT];
        sortArray[counterSORT]:= sortArray[counterSORT + 1];      // <-- 26 + 1 => Crash!
        sortArray[counterSORT + 1]:= tmp;
        unSort:= true;
       end;
     end;
   end;
end;
Alles klar?

btw: vielleicht solltest du noch mal über meinen Vorschlag aus Beitrag #14 nachdenken...

Gruß Hawkeye

markusl 19. Jun 2006 13:33

Re: Variablen sortieren
 
Neben dem, was Hawkeye geschrieben hat, ist das Hauptproblem folgende Zeile:

Zitat:

Delphi-Quellcode:
sortArray[counterCOPY]:= countArray[counterSORT + 64];

Richtig wäre

Delphi-Quellcode:
sortArray[counterCOPY]:= countArray[counterCOPY + 64];
Kann Dir empfehlen für deine Tests auf jeden Fall das Range Checking im Compiler zu aktivieren (Menü Projekt -> Optionen -> Compiler -> Range Checking).

Oder den betroffenen Code mit

{$R+}
<Code>
{$R-} umgeben

Desweiteren wurde ja schon gesagt, dass die beiden geschachtelten Schleifen eigentlich nicht nötig sind und
unnötig Rechenzeit kosten. Im ungünstigsten Fall, wenn dein Text nur aus "Z" besteht hast du das schlechteste Laufzeitverhalten.


HTH

Markus

the_source 19. Jun 2006 18:08

Re: Variablen sortieren
 
Ah danke, einfach nur die Variablen vertauscht.

So, es läuft, ich bin zufrieden. Jetzt wäre es noch toll, wenn ich diese riesige Liste an Zuweisungen wegbekäme.

Delphi-Quellcode:
OutA.Caption:= IntToStr(countArray[65]);
OutB.Caption:= IntToStr(countArray[66]);
OutC.Caption:= IntToStr(countArray[67]);
usw...

das ganze gibts dann bis 26 und insgesamt 3 mal (einmal für Label, einmal mür Max-Wert der Anzeige und nochmal für den Wert der Anzeige) und das muss doch sicherlich nicht sein.

Darum meine Frage: wie kann ich daraus eine Schleife machen?

nailor 19. Jun 2006 18:27

Re: Variablen sortieren
 
du packst deine OutX's (sagen wir mal es sind Label) in ein "Array of Label" (das musst du wohl oder übel dann einmal machen) und dann kannst du bei allen weiteren Vorkommen die Schleife nehmen

the_source 19. Jun 2006 20:11

Re: Variablen sortieren
 
hmm also habs mal zum testen erstellt, aber irgendwie blick ich nicht ganz durch. Ich kann dem Array keinen Typ "Label" geben, dann meckert er. Und wie muss ich dann später den Namen der Labels einfügen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz