Entwickler-Ecke

Sonstiges (Delphi) - Array Zahlen löschen


Dude566 - Di 16.09.08 09:03
Titel: Array Zahlen löschen
Hallo ich möchte Zahlen aus einem Array löschen, wie kann ich das am besten anstellen?
Wenn man die Zahl an der 4. Stelle löscht, sollen die nächsten mit der Stelle weiterrutschen.

Hoffe auf Hilfe.

Gruß


AXMD - Di 16.09.08 09:21

Da wird dir wohl nichts anderes übrigbleiben als dir das selbst zu programmieren (so wie du es beschrieben hast). Alternativ hilft dir die Forensuche weiter.

AXMD


Dunkel - Di 16.09.08 10:17

Ein Nachfahre von TList ist wesentlich komfortabler zu handhaben als ein Array; OOP-konformer ist es ebenfalls.


Bergmann89 - Di 16.09.08 14:25

HI,

nehmen wir an du hast 10 Stellen in deinem Array (0-9). Du willst Stelle 4 löschen, also muss Stelle 4 mit Stelle 5 überschrieben werden, Stelle 5 mit Stelle 6, ... usw
Um das machen bietet sich ne For-Sschleife an:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var MyArray: Array of Integer;
SetLength(MyArray,10); //länge des Arrays festlegen

procedure Del(Index: Integer);
var i: Integer;
begin
  for i := Index to High(MyArray)-1 do //von der Stelle die gelöscht werden soll, bis zum vorletzten Element
    MyArray[i] := MayArray[i+1]; //werte an vorderes Element übergeben also weiter rutschen
  SetLength(MyArray,Length(MyArray)-1); //neue länge ist die Alte Länge-1 also 
                                        //zuzusagen das letzte Element aus dem Array entfernen
end;


so das wars auch schon! jetzt kannst du irgendwo im Prog Del(3); aufrufen und das 4. Element wird gelöscht!

MfG Bergmann.


Dude566 - Di 16.09.08 16:41

Ja also ich bin noch Anfänger und so sonderlich viel Technike habe wir auch nicht, das ganze kommt mir Chinesisch vor.
Es muss bestimmt auch leichtere Möglichkeiten geben.
Hier mal der Quellcode des bisherigen Programms, damit ihr seht wie weit ich im Lernstoff bin.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    ListBox1: TListBox;
    Label1: TLabel;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    Button2: TButton;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Button3: TButton;
    Edit5: TEdit;
    Button4: TButton;
    Label2: TLabel;
    Label3: TLabel;
    Button5: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  zahlen : array [1..1000of integer;
  i: integer;
  zaehler : integer;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);   // Zahlen werden gespeichert
begin
zahlen [i]:= StrToInt (edit1.text);
ListBox1.Items.Add (IntToStr(zahlen[i]));
i:= i+1;
zaehler := zaehler +1 ;
Label1.Caption:= ' Sie haben ' + IntToStr (zaehler) + '  Zahlen gespeichert';
end;

procedure TForm1.FormCreate(Sender: TObject);  // Zaehler Startzahl
begin
 zaehler := 0;
end;

procedure TForm1.Button2Click(Sender: TObject);  // Filter mit Radiobutton anwenden
begin
  ListBox1.Clear;
  if RadioButton1.Checked then
   for i := 1 to zaehler do
                        if (zahlen[i] >= StrToInt(Edit2.Text)) and  (zahlen[i] <= StrToInt(Edit3.Text)) then ListBox1.Items.Add(IntToStr(zahlen[i]));
   for i := 1 to zaehler do
                        if (zahlen[i] >= StrToInt (Edit2.Text)) and (zahlen[i] <= StrToInt(Edit3.Text)) then Listbox1.Items.Add(IntToStr(zahlen[i]));

end;

procedure TForm1.Button3Click(Sender: TObject);   // Suchfunktion
  var
  i, suchzahl : integer;
  gefunden : boolean;
  zahlen_sind_gleich : boolean;
begin
  gefunden := false;
  suchzahl := StrToInt(Edit4.Text);
  for i := 1 to zaehler do
  begin
  zahlen_sind_gleich := zahlen[i] = suchzahl;
  if zahlen_sind_gleich then
                        begin
                        gefunden := true;
                        ShowMessage ('Die Zahl '+Edit4.Text+' wurde an der '+IntToStr(i)+' gefunden.');
                        end;
  end;

  if not gefunden then ShowMessage ('Die Zahl wurde nicht gefunden.');

end;

end.


elundril - Di 16.09.08 16:44

das ist aber nun mal die leichteste methode! Sonst kenn ich auch keine. arrays bringen nun mal keine methoden mit die das für einen erledigen, man muss alles per hand machen.

lg elundril


jome - Di 16.09.08 21:53

Hallo Dude566,

Im Prinzip hast Du richtig gedacht. Aber die Erfahrung zeigt, dass für Deinen Zweck die Verwendung eines (statischen) Arrays nicht zu empfehlen ist. "Dunkel" hat natürlich recht. Ein TList Nachfolger wäre am besten geeignet:

Am besten TStringlist.

1. Du deklarierst privat in der Unit (private Teil des Forms TForm1) das Objekt Suchliste : TStringlist.
2. Dann erzeugt Du dieses Objekt im Create-Eventhandler des Forms (Suchliste:=TStringlist.create)
3. Am besten gleich angewöhnen, dieses Objekt im Destructor (Destroy-Eventhandler des Forms) wieder zu zerstören: FreeAndNil(Suchliste) oder Suchliste.free
4. Der Rest ist äußerst bequem. Dein Array kannst du vergessen. Deine Zahlen kommen ab jetzt in die Suchliste:

Hinzufügen eines Eintrags: Suchliste.add(Inttostr(NeueZahl));
Löschen eines Eintrags: Suchliste.Delete(Index); -> alle anderen Einträge rücken automatisch nach
Suchen einer Zahl: I:=Suchliste.IndexOf(Inttostr(Suchzahl)); -> Rückgabe I ist der gefundene Index (-1 heisst nicht gefunden)
Anzahl der Einträge bestimmen: I:=Suchliste.count;

Deine Suchprozedur vereinfacht sich auf:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button3Click(Sender: TObject);   // Suchfunktion  
  var  
  i: integer;  
  gefunden : boolean;   
begin  
  
  i:=Suchliste.IndexOf(Edit4.Text);
  gefunden:=I>-1;
  
If gefunden then
   ShowMessage ('Die Zahl '+Edit4.Text+' wurde an der '+IntToStr(i)+' gefunden.'
  else
   ShowMessage ('Die Zahl wurde nicht gefunden.'); 
 
end;



Servus
Jome


elundril - Mi 17.09.08 15:19

macht indexof nicht genau das selbe wie die schleife? da wäre es doch blöd dann ewig viele stringverleiche und stringoperationen zu machen obwohl man das auch mit einem Integer-array machen könnte?

aber ich würd von einem statischen array auf ein dynamisches array umsteigen.

lg elundril


Dunkel - Mi 17.09.08 15:42

user profile iconelundril hat folgendes geschrieben:
aber ich würd von einem statischen array auf ein dynamisches array umsteigen.

Und ich würde es mit einer TObjectList machen. Dann muss man zwar ein wenig zwischen TObject & Integer hin und her casten, ist IMHO aber performanter als ständig mit IntToStr & StrToInt zu hantieren; von dem Krampf mit einem Array würde ich komplett abraten.


Dude566 - Mi 17.09.08 16:26

Ja ich glaub euch das diese Lösungen besser sind, unser Lehrer wollte es so haben, und nichts neues hinzu. :(
Naja mal sehen wie der Test wird.


Dude566 - Do 18.09.08 17:22

Also ich habe das ganze jetzt so gelöst:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Edit2: TEdit;
    Label2: TLabel;
    Edit3: TEdit;
    Label3: TLabel;
    RadioGroup1: TRadioGroup;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    RadioButton3: TRadioButton;
    RadioButton4: TRadioButton;
    ListBox1: TListBox;
    Edit4: TEdit;
    Label4: TLabel;
    Edit5: TEdit;
    Label5: TLabel;
    Button1: TButton;
    Button2: TButton;
    Label6: TLabel;
    Button3: TButton;
    Button4: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  zahlen : Array [1..100of integer;
  i : integer;
  gesucht : integer;
  gefunden : boolean;
  geloescht : boolean;
  counter : integer;
  max : integer;
  min : integer;


implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  counter := 0;
  i := 1;
  gefunden := false;
end;

procedure TForm1.Button1Click(Sender: TObject);      // Speichern
begin
  if counter = 100 then ShowMessage ('Das Array ist voll, bitte keine Zahlen mehr einspeichern.')
                   else begin
  counter := counter+1;
  zahlen[counter] := StrToInt(Edit1.Text);
  Label6.Caption := ('Sie haben ' +IntToStr(counter)+(' Zahlen im Array gespeichert.'));
  Edit1.Clear;
                   end;
end;

procedure TForm1.Button2Click(Sender: TObject);    // Ausgeben
begin
  ListBox1.Clear;
  if RadioButton1.Checked then for i := 1 to counter do ListBox1.Items.Add(IntToStr(zahlen[i]));
  if RadioButton2.Checked then begin
                               min := StrToInt(Edit4.Text);
                               max := StrToInt(Edit5.Text);
                               for i := 1 to counter do begin
                               if (zahlen[i]> min) and (zahlen[i]< max) then ListBox1.Items.Add(IntToStr(zahlen[i]));
                                                        end
                               end;
end;

procedure TForm1.Button3Click(Sender: TObject);  // Suchen
begin
 gesucht := StrToInt(Edit2.Text);
for i:= 1 to counter do if gesucht = zahlen[i] then
    begin
    showmessage('Die Zahl '+(IntToStr(gesucht))+' wurde an der '+(IntToStr(i))+'. Stelle gefunden');
    gefunden := true;
    end;
if gefunden = false then showmessage('Die gesuchte Zahl '+(IntToStr(gesucht))+' ist nicht zu finden') ;

end;

procedure TForm1.Button4Click(Sender: TObject);    // Löschen
var
stelle, loeschen : integer;
begin
  loeschen := StrToInt(Edit3.Text);
   for i:=1 to counter do if zahlen[i] = loeschen then stelle := i;
   counter := counter -1;
   for i := stelle to counter do zahlen[i] := zahlen[i+1];
   ListBox1.Clear;
   for i := 1 to counter do ListBox1.Items.Add(IntToStr(zahlen[i]));
end;

end.


elundril - Do 18.09.08 17:26

schon mal getestet? da wird denk ich der compiler meckern weil du eigentlich nicht auf die schleifenvariable zugreifen darfst!

und so würde das ganze gut formatiert aussehen, das macht das lesen einfacher ;-):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.Button4Click(Sender: TObject);    // Löschen 
var stelle, loeschen : integer; 
begin 
  loeschen := StrToInt(Edit3.Text); 
  for i:=1 to counter do 
    if zahlen[i] = loeschen then stelle := i; 
  counter := counter -1
  for i := stelle to counter do 
    zahlen[i] := zahlen[i+1]; 
  ListBox1.Clear; 
  for i := 1 to counter do 
    ListBox1.Items.Add(IntToStr(zahlen[i])); 
end;


lg elundril


Dude566 - Do 18.09.08 17:34

Ja es klappt, der einzigste Bug ist, das wenn man eine Zahl eingibt die es nicht gibt löscht er die 1. ^^
Ne Antwort darauf?
Ich schreibe morgen einen Test. :(


elundril - Do 18.09.08 17:36

aso, stimmt, counter ist global bei dir definiert und nicht lokal. sorry!


Dude566 - Do 18.09.08 17:39

Kein Problem, vielleicht ne Lösung für das Problem?


Bergmann89 - Do 18.09.08 17:40

ja:
du hast Stelle am anfang keinen wert gegeben! Wenn also die zahl nich gefunden wird, dann nimmt er die zahl die Stelle hat und das ist in dem fall 0!
machs doch so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.Button4Click(Sender: TObject);    // Löschen 
var stelle, loeschen : integer; 
begin 
  Stelle := -1;
  loeschen := StrToInt(Edit3.Text); 
  for i:=1 to counter do 
    if zahlen[i] = loeschen then stelle := i; 
  counter := counter -1
  if stelle <> -1 then
    for i := stelle to counter do 
      zahlen[i] := zahlen[i+1]; 
  ListBox1.Clear; 
  for i := 1 to counter do 
    ListBox1.Items.Add(IntToStr(zahlen[i])); 
end;


MfG Bergmann.


Knulli - Do 18.09.08 19:17

Hi Dude...

schon mal sowas versucht?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.Button3Click(Sender: TObject);
var
  MeinArray: Array[1..10of Integer;
  x: Integer;
  procedure Del(aPosn: Integer);
  begin
    CopyMemory(@MeinArray[aPosn], @MeinArray[aPosn+1], (Length(MeinArray)-aPosn)*SizeOf(Integer));
  end;
begin
  for x := Low(MeinArray) to High(MeinArray) do MeinArray[x] := x;

  Del(5);

end;

Knulli


Dude566 - Do 18.09.08 19:58

user profile iconKnulli hat folgendes geschrieben:
Hi Dude...

schon mal sowas versucht?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.Button3Click(Sender: TObject);
var
  MeinArray: Array[1..10of Integer;
  x: Integer;
  procedure Del(aPosn: Integer);
  begin
    CopyMemory(@MeinArray[aPosn], @MeinArray[aPosn+1], (Length(MeinArray)-aPosn)*SizeOf(Integer));
  end;
begin
  for x := Low(MeinArray) to High(MeinArray) do MeinArray[x] := x;

  Del(5);

end;

Knulli


Sowas haben wir noch nicht gemacht, ich denke nicht das er es akzeptieren wird.