Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - dynamisches Array erste Elemente löschen


daywalker0086 - Mi 03.12.08 17:26
Titel: dynamisches Array erste Elemente löschen
ich schonwieder...
Wie bekomm ich es hin in einem dynamischen array alles werte 2 oder drei felder nach vorn zu schieben und hinter wieder nullwerte einzufügen?
Die ersten 2 werte der Felder gehen dabei verloren was auch gewollt ist.
Hinten müssen wieder 2 mal nullen eingefügt werden damit das array seine länge behält und nicht kürzer wird.


jaenicke - Mi 03.12.08 17:50

Bei einem dynamischen Array würde ich vermuten, dass du dann die Länge auch verkleinern würdest, aber wo liegt denn das Problem beim Verschieben?
An Position 0 muss Element 0 + 2, an Position 1 Element 1 + 2 usw., am Ende dann noch die Nullen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure DelArrayLeft(var a: array of Integer; uCount: Integer);
var
  i: Integer;
begin
  for i := 0 to High(a) - uCount do
    a[i] := a[i + uCount];
  for i := Length(a) - uCount to High(a) do
    a[i] := 0;
end;


elundril - Mi 03.12.08 17:53

gibts nicht so nen befehl wie copy der die erste schleife ersetzt?

lg elundril


jaenicke - Mi 03.12.08 17:55

Copy geht auch für Arrays, aber ich will ja nix kopieren. ;-)
(Und Slice schneidet einen Teil eines Arrays aus.)


daywalker0086 - Mi 03.12.08 18:04

Achso hab ich vergessen: das array ist vom typ string
also muss ich ucount auf 2 setzen damit er mir die elemente um 2 felder nach vorn verschiebt oder wie?
ich steig noch nicht ganz durch deine schleife durch
hab das jetzt so aber funzt irgendwie nicht, meckert über zugriffsverletzungen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
 
ucount:= 3;
           for i := 0 to High(daten) - uCount do
           Daten[i] := Daten[i + uCount];
           for i := Length(Daten) - uCount to High(Daten) do
           Daten[i] := '0000';


jaenicke - Mi 03.12.08 18:10

Das einzige was du ändern musst ist der Typ des Arrays, dann kannst du die Prozedur normal aufrufen, in der Prozedur musst du gar nix ändern, der Wert uCount wird ja als Parameter übergeben.

Delphi-Quelltext
1:
procedure DelArrayLeft(var a: array of String; uCount: Integer);                    


daywalker0086 - Mi 03.12.08 18:16

und was für einen wert soll ich für ucount übergeben?
es kommt immer die meldung ... ist kein gültiger integerwert


jaenicke - Mi 03.12.08 18:25

2 in deinem Fall.

Delphi-Quelltext
1:
DelArrayLeft(DeinArray, 2);                    


Delete - Mi 03.12.08 23:09

Man könnte auch, die letzten zwei Elemente auf das erst und zweite Element kopieren und dann die letzte beiden Elemente mit nullen / leeren Strings füllen. Natürlich geht dabei die Sortierung verloren ofern vorhanden. Aber ein neu Sortieren mit einem effektiven Algorithmus ist bestimmt effektiver, als alle Elemente zu kopieren.

Man könnte auch das Array durch eine verkettete Liste ersetzen und dann die Zeiger alle entsprechend umbiegen.

Oder man nimmt eine T(Object)List und speichert in dieser die Strings.


Boldar - Mi 03.12.08 23:13

oder man macht das array als pointer, reserviert da ausreichend speicher und biegt den Pointer dann um.


delfiphan - Mi 03.12.08 23:26

Die ersten zwei Elemente mit Finalize freigeben. n-2 Elemente mit move verschieben. Die letzten beiden Elemente mit FillChar oder ZeroMemory auf 0 setzen.

PS: Je nach Typ (z.B. Integer) wird der Finalize Aufruf ignoriert, was aber nicht stört. FillChar oder Move sollte nicht ersetzt werden durch eine For-Schleife mit Zuweisungen, sonst gibt's Probleme bei referenzgezählten Typen. Wenn, dann beide durch For-Schleifen ersetzen. Dann leidet aber die Performance darunter.