Thema: Delphi Arrays auswerten

Einzelnen Beitrag anzeigen

marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: Arrays auswerten

  Alt 1. Dez 2006, 08:08
Herzlich willkommen in der Delphi-PRAXiS, rambospike.

Es wird alles viel einfacher für dich, wenn du erstmal einen groben Fahrplan aufstellst:
  • (1) Zahlen bereitstellen
  • (2) Nach Zahlwert sortieren
  • (3) Kettenlängen bestimmen
  • (4) Nach Kettenlänge sortieren

Zur Visualisierung schlage ich dir eine ListBox vor. Die Eingabe ersetze ich durch Zufallszahlen:

Delphi-Quellcode:
const
  MAX_ITEMS = 20;

// (1) Zahlen bereitstellen
procedure Initialize(s: TStrings);
begin
  with s do
  begin
    Clear;
    while Count < MAX_ITEMS do
      Add(IntToStr(Random(10)));
  end;
end;
Das Sortieren der Zahlenwerte kannst du mit einem beliebigen Verfahren erledigen. Ich nehme jetzt mal den BubbleSort:

Delphi-Quellcode:
// (2) Nach Zahlwert sortieren
procedure BubbleSort(s: TStrings);
var
  iInner, iOuter: Integer;
begin
  with s do
    for iOuter := 1 to Pred(Count) do
      for iInner := Pred(iOuter) downto 0 do
        if StrToInt(Strings[iInner]) > StrToInt(Strings[Succ(iInner)])
          then Exchange(iInner, Succ(iInner))
          else Break;
end;
Die Zahlenwerte sind jetzt geordnet und gleiche Zahlen stehen direkt hintereinander. Um die Sortierung nach Kettenlänge in Schritt 4 zu vereinfachen führe ich eine Lauflängenverdichtung ein. Die Folge 0 0 0 0 0 ersetze ich durch 0 (5 mal). Den Wiederholungsfaktor verstecke ich in der Array-Eigenschaft Objects[] der ListBox.Items:

Delphi-Quellcode:
// (3) Kettenlängen bestimmen
procedure RLEncode(s: TStrings);
var
  iInner, iOuter, iCount: Integer;
begin
  with s do
  begin
    if Count > 0
      then iOuter := 0
      else Exit;
    while iOuter < Count do
    begin
      iCount := 1;
      iInner := Succ(iOuter);
      while (iInner < Count)
      and (Strings[iInner] = Strings[iOuter]) do
      begin
        Inc(iCount);
        Delete(iInner);
      end;
      Objects[iOuter] := Pointer(iCount);
      Inc(iOuter);
    end;
  end;
end;
Jetzt können wir den BubbleSort aus Schritt 2 leicht modifiziert verwenden um nach Lauflänge zu sortieren:

Delphi-Quellcode:
// (4) Nach Kettenlänge sortieren
procedure ChainSort(s: TStrings);
var
  iInner, iOuter: Integer;
begin
  with s do
    for iOuter := 1 to Pred(Count) do
      for iInner := Pred(iOuter) downto 0 do
        if Integer(Objects[iInner]) > Integer(Objects[Succ(iInner)])
          then Exchange(iInner, Succ(iInner))
          else Break;
end;
Du und ich wir wissen jetzt bereits, dass wir fertig sind, aber damit der Rest der Welt uns das auch glaubt, bauen wir die Anzeige noch um, so dass die Lauflänge in runden Klammern hinter der Zahl erscheint:

Delphi-Quellcode:
// (5) Visualisierung
procedure Visualize(s: TStrings);
var
  i: Integer;
begin
  with s do
    for i := 0 to Pred(Count) do
      Strings[i] := Format('%s (%d)', [Strings[i], Integer(Objects[i])]);
end;
Packe eine ListBox auf eine leere Form und verpasse der Form einen Event Handler für OnCreate():

Delphi-Quellcode:
procedure TDemoForm.FormCreate(Sender: TObject);
begin
  Randomize;
  Initialize(ListBox.Items);
  BubbleSort(ListBox.Items);
  RLEncode(ListBox.Items);
  ChainSort(ListBox.Items);
  Visualize(ListBox.Items);
end;
Deine Aufgabe ist es jetzt, den Code Zeile für Zeile anhand der Delphi Online Hilfe nachzuvollziehen. Sobald du ihn verstanden hast, wirst du ihn an deine Aufgabe anpassen können. Baue noch eine Benutzerschnittstelle, die die einzelnen Schritte etwas entzerrt und du bist fertig.

Freundliche Grüße vom marabu
  Mit Zitat antworten Zitat