Wo hast du um Gottes Willen diesen grauenhaften Code her?
- Keinerei Kommentare
- Völig nichtssagende Variablennamen, noch dazu lauter globale statt lokale variable
- repeat-Schleifen, wo for-Schleifen angebracht wären
- Das Feld Zahlen wird selbst gar nicht sortiert, sondern die Zahlen werden nur in die Ausgabelistbox geschaufelt
- Prinzipiell sollte man die Programmlogik von den Ereignisbehandlungsroutinen trennen
- Das Programm ist noch dazu fehlerhaft: Wenn zufällig beim Initialisieren in dem Feld mehrmals die gleiche Zahl generiert wird, funktioniert es nicht mehr, weil in jedem Durchlauf nach einer Zahl gesucht wird, die grösser ist als die bisher schon ausgegebenen Zahlen. Jede Zahl wird folglich nur einmal in die Ausgabeliste aufgenommen, und am Ende findet er keine passende Zahl mehr und gibt folglich den Wert 101 aus, mit dem k am Anfang jedes Durchlaufs initiaisiert wird.
Der Sort funktioniert nach dem Prizip, dass in jedem äusseren Schleifendurchauf die kleinste Zahl gesucht wird, die noch nicht in die Ausgabeliste übertragen worden ist. Die größte Zahl, die schon "erledigt" ist, merkt es sich in der Variable g, die im aktuellen Durchlauf kleinste noch nicht erledigte Zahl in der Variable k.
Hier das ganze in halbwegs lesbarer Form, dann verstehst du vielleicht besser, wie das fuktioniert (der Fehler ist hier aber nicht behoben).
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
const
maxzahl=100; // grösste Zahl
maxindex=20; // Feldgrösse
type
{ TForm1 }
TForm1 = class(TForm)
B_ordnen: TButton;
B_zahlen: TButton;
LB_ausgabe: TListBox;
LB_ausgabe2: TListBox;
procedure B_ordnenClick(Sender: TObject);
procedure B_zahlenClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
zahlen: ARRAY[1..maxindex] of Integer;
implementation
{$R *.lfm}
procedure Feld_Initialisieren;
var i: integer;
begin
LB_Ausgabe.Clear;
for i:=1 to maxindex do
begin
Zahlen[i]:=Random(maxzahl)+1; // Zufallszahl zwischen 1 und maxzahl
LB_Ausgabe.Items.Add(InttoStr(zahlen[i]));
end;
end;
procedure Sortierte_Ausgabe;
// funktioniert aber nur, wenn im Feld nur verschiedene Zahlen vorkommen
var durchlauf,i, grösstes_erledigtes, kleinstes_gefundenes: integer;
begin
LB_Ausgabe2.clear ;
grösstes_erledigtes := 0;
for durchlauf:=1 to maxindex do
begin // In jedem Durchlauf die kleinste noch nicht erledigte Zahl ausgeben
kleinstes_gefundenes:=maxzahl+1;
for i:=1 to maxindex do
if (zahlen[i]<kleinstes_gefundenes) and (zahlen[i]>grösstes_erledigtes)
then kleinstes_gefundenes:=zahlen[i];
LB_Ausgabe2.Items.Add(InttoStr(kleinstes_gefundenes));
grösstes_erledigtes:=kleinstes_gefundenes;
end;
end;
{ TForm1 Ereigisbehandlung }
procedure TForm1.FormCreate(Sender: TObject);
begin
randomize
end;
procedure TForm1.B_zahlenClick(Sender: TObject);
begin
Feld_Initialisieren
ened;
procedure TForm1.B_ordnenClick(Sender: TObject);
begin
Sortierte_Ausgabe;
end;
end.
edit:
Und hier noch eine Variation, die den Fehler korrigiert, indem man sich von einem Durchlauf zum nächsten merkt, an welcher Position die kleinste Zahl gefunden wurde
Code: Alles auswählen
procedure Sortierte_Ausgabe;
var durchlauf,i, grösstes_erledigtes, kleinstes_gefundenes,
i_grösstes, i_kleinstes: integer;
begin
LB_Ausgabe2.clear ;
grösstes_erledigtes := 0; i_grösstes:=maxindex+1;
for durchlauf:=1 to maxindex do
begin // In jedem Durchlauf die kleinste noch nicht erledigte Zahl ausgeben
kleinstes_gefundenes:=maxzahl+1;
for i:=1 to maxindex do
if (zahlen[i]>grösstes_erledigtes) // ist noch nicht ausgegeben worden
and (zahlen[i]<kleinstes_gefundenes) // kleinste noch nicht ausgegebene Zahl
then begin
kleinstes_gefundenes:=zahlen[i];
i_kleinstes:=i
end
else
if (zahlen[i]=grösstes_erledigtes) // Zahl, gleich gross wie die im vorigen Durchgang ausgegebene
and (i>i_grösstes) // aber weiter hinten im Feld
then begin
kleinstes_gefundenes:=zahlen[i]; // die Zahl noch einmal ausgeben
i_kleinstes:=i;
// Das break ist hier unbedingt nötig, für den Fall,
// dass drei oder mehr gleich grosse Zahlen im Feld vorkommen
break;
end;
LB_Ausgabe2.Items.Add(InttoStr(kleinstes_gefundenes));
grösstes_erledigtes:=kleinstes_gefundenes;
i_grösstes := i_kleinstes;
end;
end;