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