Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Arrays auswerten (https://www.delphipraxis.net/81652-arrays-auswerten.html)

rambospike 30. Nov 2006 20:43


Arrays auswerten
 
Hallo zusammen,

ich habe ein kleines Problem. Ich möchte in ein Edit Feld eine Zahl von 1-10 eingeben. Diese Zahl soll nach Betätigung des OK. Button in ein Label geschrieben werden. Dann soll der Eingabefocus wieder in das Edit Feld gelegt werden. Bis hierhin bin ich gekommen.

Jetzt soll die nächste Zahl von 1-10 eingegeben werden. Die neue Zahl soll nun in das Label der vorherigen Zahl geschrieben werden. Und so weiter. Wenn das letzte der 10 Labels mit Zahlen gefüllt ist, soll die zuerst eingegebene Zahl verschwinden und die elfte Zahl oben erscheinen.

Aus diesen Zahlen soll nun jeweils ermittelt werden, ob zwei Zahlen identisch(Zwillinge) sind. Der erste Zwilling soll nun in das erste Label mit Namen Zwilling geschrieben werden. Dann soll so vorgegangen werden wie bei den anderen Zahlen, die Zwillinge sollen weiter nach unten wandern.

Aus den Zwillingen sollen Drillinge ermittelt werden, ansonsten wie vor.
Zum schluss sollen aus den Drillingen die Vierlinge ermittelt werden.

Und das alles immer fortlaufend.

Zur besseren Übersicht habe ich mal den bisherigen Quellcode beigefügt. Wäre schön, wenn mir jemand helfen könnte.

Vielen Dank.

Delphi-Quellcode:
unit Zwillinge;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Zahl: Array [1..10] of Integer;
  Zwilling: Array [1..5] of Integer;
  Drilling: Array [1..3] of integer;
  Vierling: Array [1..2] of Integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
label1.Caption:=inttostr (Zahl[1]);
end;

end.
[edit=SirThornberry]Delphi-Tags gesetzt - Mfg, SirThornberry[/edit]

marabu 1. Dez 2006 08:08

Re: Arrays auswerten
 
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

oldmax 1. Dez 2006 08:41

Re: Arrays auswerten
 
Hi
Erst mal Willkommen.
Nun, deine Beschreibung ist, ehrlich gesagt etwas für die Glaskugel. Ich vermute mal, das du die Zeichen in Form einer Laufschrift durch die Labels wandern lassen möchtest und wenn 2, 3 oder 4 auftauchen dieses ebenfals in einer Laufschriftähnlichen Form anzeigen möchtest. Sag mir, wenn ich gut geraten habe, dann mach ich beim nächsten Mal weiter.
Ich weiß, es ist nicht einfach, seine Aufgabe zu beschreiben, aber je besser du sie beschreiben kannst, un so mehr Probleme wirst du selbst lösen können.
z. B. vorgehensweise beim Programmieren einer Laufschrift.

Delphi-Quellcode:
Var Werte :Array[1..10] of integer;
Delphi-Quellcode:
Procedure Arrayvorbesetzen;
Var i: Integer;
Begin
  For i:=1 to 10 do Werte[i]:=0;
End;
nun schieben wir mal...

Delphi-Quellcode:
Procedure ArraySchieben(neuerWert: Integer);
Var i : Integer;
begin
  For i:=2 to 10 do Werte[i-1]:=Werte[i]; // schiebt von oben nach unten...
  Werte[10]:=Neuerwert;   // neuer Wert in 10. Feld
  Label1.Caption:=Werte[1];
  Label2.Caption:=Werte[2];
  Label3.Caption:=Werte[3];
  usw
end;
und andersrum schieben wäre
Delphi-Quellcode:
For i:=1 to 9 do Werte[10-i+1]:=Werte[10-i]; // schiebt von unten nach oben...
  Wert1:=Neuwert; // neuer wert in 1.Feld
viel Spass noch
Gruß oldmax

rambospike 1. Dez 2006 19:33

Re: Arrays auswerten
 
Zitat:

Zitat von oldmax
Ich vermute mal, das du die Zeichen in Form einer Laufschrift durch die Labels wandern lassen möchtest und wenn 2, 3 oder 4 auftauchen dieses ebenfals in einer Laufschriftähnlichen Form anzeigen möchtest. Sag mir, wenn ich gut geraten habe, dann mach ich beim nächsten Mal weiter.

Gruß oldmax

Hallo Oldmax,

erst einmal vielen Dank für deine Antwort. Du hast vollkommen richtig geraten. Deine Beschreibung entspricht genau dem, was ich mir vorgestellt habe. Ich werde jetzt mal versuchen, mit deinem Code weiterzukommen.

Vielen Dank nochmal.

Herzliche Grüße von

rambospike

rambospike 1. Dez 2006 19:38

Re: Arrays auswerten
 
Zitat:

Zitat von marabu
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

Hallo Marabou,

vielen Dank für deine Hilfe. Du hast dir für einen Anfänger wie mich wirklich viel Mühe gegeben. Ich werde versuchen, nach deinen Vorgaben vorzugehen. Ich hoffe, dass es mir gelingt.

Nochmals vielen Dank

herzliche Grüße von

rambospike

rambospike 1. Dez 2006 20:16

Re: Arrays auswerten
 
Zitat:

Zitat von rambospike
Zitat:

Zitat von oldmax
Ich vermute mal, das du die Zeichen in Form einer Laufschrift durch die Labels wandern lassen möchtest und wenn 2, 3 oder 4 auftauchen dieses ebenfals in einer Laufschriftähnlichen Form anzeigen möchtest. Sag mir, wenn ich gut geraten habe, dann mach ich beim nächsten Mal weiter.

Gruß oldmax

Hallo Oldmax,

erst einmal vielen Dank für deine Antwort. Du hast vollkommen richtig geraten. Deine Beschreibung entspricht genau dem, was ich mir vorgestellt habe. Ich werde jetzt mal versuchen, mit deinem Code weiterzukommen.

Vielen Dank nochmal.

Herzliche Grüße von

rambospike

Hallo nochmal,

ich habe deinen Code im Programm eingegeben, doch beim Compilieren kommt die Meldung: Undefinierter Bezeichner: 'Label2' , Label3 usw.
Ich schicke nochmal den Code zur Prüfung, vielleicht findest du ja den Fehler. Vielen Dank.

herzliche Grüße von

rambospike


unit Zwillinge;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Button1: TButton;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
Label14: TLabel;
Label15: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label19: TLabel;
Label20: TLabel;
Label21: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;
Zahl: Array [1..10] of Integer;
Zwilling: Array [1..5] of Integer;
Drilling: Array [1..3] of integer;
Vierling: Array [1..2] of Integer;

implementation

{$R *.dfm}
Procedure Arrayvorbesetzen;
Var a: Integer;
Begin
For a:=1 to 10 do Zahl[a]:=0;
End;

Procedure ArraySchieben(neuerWert: Integer);
Var a : Integer;
begin
For a:=2 to 10 do Zahl[a-1]:=Zahl[a];
// schiebt von oben nach unten...
Zahl[10]:=Neuerwert; // neuer Wert in 10.Feld
Label2.Caption:=inttostr (Zahl[1]);
Label3.Caption:=inttostr (Zahl[2]);
Label4.Caption:=inttostr (Zahl[3]);
Label5.Caption:=inttostr (Zahl[4]);
Label6.Caption:=inttostr (Zahl[5]);
Label7.Caption:=inttostr (Zahl[6]);
Label8.Caption:=inttostr (Zahl[7]);
Label9.Caption:=inttostr (Zahl[8]);
Label10.Caption:=inttostr (Zahl[9]);
Label11.Caption:=inttostr (Zahl[10]);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin



end;

end.

marabu 2. Dez 2006 17:50

Re: Arrays auswerten
 
Hallo,

Zitat:

Zitat von rambospike
... ich habe deinen [oldmax] Code im Programm eingegeben, doch beim Compilieren kommt die Meldung: Undefinierter Bezeichner: 'Label2' , Label3 ...

um auf die Komponenten Label2, Label3 etc. einfach zugreifen zu können, muss die Routine ArraySchieben() eine Methode deiner Form sein:

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Label2: TLabel;
    // ...
  private
    procedure ArraySchieben (neuerWert: Integer);
    // ...
  end;

implementation

// ...

procedure TForm1.ArraySchieben (neuerWert: Integer);
var
  a: Integer;
begin
  for a := 2 to 10 do
    Zahl[a - 1] := Zahl[a];

  // schiebt von oben nach unten...
  Zahl[10] := Neuerwert; // neuer Wert in 10.Feld
  Label2.Caption := IntToStr (Zahl[1]);
  // ...
  Label11.Caption := IntToStr (Zahl[10]);
end;
Das ist nur eine Möglichkeit - es gibt auch noch andere.

Freundliche Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:42 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