![]() |
Mehere Elemente eines Feldes löschen durch überschreiben?
Hallo, ich bin gerade dabei mit Arrays zu arbeiten und nun bin ich auf die Sache gestoßen wie man löschen kann. Allerdings soll in meiner Ausgabe (Listbox) ja dann keine freistelle sein, sondern einfach der naechste wert den gelöschten wert ueberschreiben!
Ok hört sich ziemlich seltsam an, ich probiers mal kurz an nem bsp zu erlaeutern: Index des Feldes : 1 2 3 4 5 Zahl des Feldes : 3 2 4 2 6 Wenn ich jetzt mag das die Zahl 2 gelöscht wird dann würde ja 3 '' 4 '' 6 und ich mag halt das 3 4 6 da steht.. und natuerlich nur die indizies 1-3 geklappt hat dies alles auch wunderbar wenn die zahl nur 1x vorkommt, allerdings sobald es oefter gelöscht werden muss bin ich am scheitern.. bis her sieht meine prozedure so aus const af=5;
Delphi-Quellcode:
j is einfach der Index wo die 2 steht, gesucht wurde diese stelle durch eine lineare suche...
procedure loeschen(var j:integer);
var i:integer; //Zaehlervariable begin for i:=j to af-1 do a[i]:=a[i+1]; a[af]:=0; dec(af); end; so das war jetzt fuer 1 element löschen und nun hab ich das so geschrieben fuer mehere
Delphi-Quellcode:
funzt aber nicht, könntet ihr mir vllt verraten wie das geht?
procedure var1(var a:ta; var af:integer; key:te);
var i,temp,afneu:integer; begin afneu:=af; temp:=0; for i:=1 to af do if uppercase(a[i]) = uppercase(key) then begin for temp:=i to af do a[temp]:=a[temp+1]; a[afneu]:=' '; dec(afneu); end aber bitte sagt mir nicht das ich einfach ne andere art von löschen benutzen soll, andere varianten habe ich schon, ich brauch halt nur noch diese |
Re: Mehere Elemente eines Feldes löschen durch überschreiben
Hi Lotus,
vielleicht hilft es Dir:
Delphi-Quellcode:
Frage vorweggenommen:
type
TCharArray = array of Char; TByteArray = array of Byte; function Kill(const Kill:Char;const StrArr:TCharArray):TCharArray; var i,Count : Word; ToKill : Byte; tempByteArr : TByteArray absolute StrArr; begin ToKill := ORD(Kill); Count := 0; for i := Low(StrArr) to High(StrArr) do begin if (tempByteArr[i]<>ToKill) then begin INC(Count); SetLength(result,Count); result[count-1] := StrArr[i]; end; end; end; function KillAndFill(const Kill,Fill:Char;const StrArr:TCharArray):TCharArray; var i : Word; ToKill : Byte; tempByteArr : TByteArray absolute StrArr; begin ToKill := ORD(Kill); SetLength(result,High(StrArr)+1); for i := Low(StrArr) to High(StrArr) do begin if (tempByteArr[i]<>ToKill) then result[i] := StrArr[i] else result[i] := Fill; end; end; tempByteArr : TByteArray absolute StrArr zeigt auf den gleichen Bereich im Speicher, wie auch const StrArr:TCharArray. Die vergleichsoperation (tempByteArr[i]<>ToKill) wird vom Compiler (da jetzt ein definierter Byte-Vergleich) viel effizenter umgesetzt. Kann bei vielen aufrufen der Funktion von Vorteil sein. Kill : Loescht und gibt ein kuerzeres Array zurueck. KillAndFill : Ersetzt. |
Re: Mehere Elemente eines Feldes löschen durch überschreiben
@LoCrux:
Ich würde KILL so aufbauen :
Delphi-Quellcode:
Warum ?:
PROCEDURE xKill(kill:char; var StrArr:TCharArray);
var i,j:integer; begin j:=0; for i:=0 to High(StrArr) do if StrArr[i]<>kill then begin StrArr[j]:=StrArr[i]; inc(j); end; SetLength(StrArr,j); end; Weil bei deiner Version SetLength wiederholt aufgerufen wird, nämlich für jeden Char, der nicht gelöscht wird. Bei XKill nur einmal! Bei Length(StrArr) = 10 habe ich gemessen Für deine Version 4584 CPU-Ticks Für meine Version 548 CPU-Ticks Die Vervendung von Byte statt Char bringt meines Erachtens nichts, denn Char und Byte werden identisch abgewickelt. Und zum Nachprüfen die Prozedur, mit der ich das getestet habe.
Delphi-Quellcode:
PROCEDURE TMain.Test;
var ta:TCharArray; i,n:integer; t0,t1,t2:Int64; s1,s2:string; FUNCTION TimeStamp:Int64; asm rdtsc; end; begin t1:=High(int64); t2:=High(int64); for n:=1 to 10 do begin // Ticks für KILL messen setlength(ta,10); for i:=0 to 9 do ta[i]:=Chr(Ord('a')+i); t0:=TimeStamp; ta:=Kill('c',ta); t0:=TimeStamp-t0; if t0<t1 then t1:=t0; s1:=''; // Nur zur Kontrolle, ob die for i:=0 to high(ta) do s1:=s1+ta[i]; // Ergebnisse idenstisch sind // Ticks für xKILL messen setlength(ta,10); for i:=0 to 9 do ta[i]:=Chr(Ord('a')+i); t0:=TimeStamp; xKill('c',ta); t0:=TimeStamp-t0; if t0<t2 then t2:=t0; s2:=''; // Nur zur Kontrolle, ob die for i:=0 to high(ta) do s2:=s2+ta[i]; // Ergebnisse idenstisch sind end; showmessage(s1+' '+IntToStr(t1)+#13+s2+' '+IntToStr(t2)); end; |
Re: Mehere Elemente eines Feldes löschen durch überschreiben
@Amateurprofi
OK! Keine Einwaende (war ja auch nur Qick'N'Dirty direkt reingetippt). Zitat:
dass ich mal auf 'ner CodeGear-Seite was darueber gelesen hab. Ging da glaub um Suchen nach bestimmten Patterns in grossen Textdateien. Dann aendern wir aber auch
Delphi-Quellcode:
procedure KillAndFill(const Kill,Fill:Char;var StrArr:TCharArray);
var i : Integer; begin for i := 0 to High(StrArr) do if (StrArr[i]=Kill) then StrArr[i] := Fill; end; |
Re: Mehere Elemente eines Feldes löschen durch überschreiben
also erstmal danke euch beiden für die schnelle antworten, allerdings muss ich sagen das ich noch "relativ" neu bin und wir leider in der schule nicht wirklich irgendwie solch einen quelltext schreiben, dieses ganze TCharArray und StrARR oder so damit komm ich irgendwie noch nich ganz so klar
Delphi-Quellcode:
das versteh ich aber schon einigermaßen und ich werds mal so probieren..
PROCEDURE xKill(kill:char; var StrArr:TCharArray);
var i,j:integer; begin j:=0; for i:=0 to High(StrArr) do if StrArr[i]<>kill then begin StrArr[j]:=StrArr[i]; inc(j); end; SetLength(StrArr,j); end; |
Re: Mehere Elemente eines Feldes löschen durch überschreiben
@Lotus
Zitat:
Du kannst z.b. scheiben:
Delphi-Quellcode:
Damit wird jede Variable vom Typ TMyInteger zum einem Integer-Typen. Analog geht das mit Arrays.
TMyInteger = Integer;
Wenn Du eine Variable EineMenge : Array[0..10] of Char; deklariest, kannst Du vorher auch einen einen Typ TEineStatischeMenge : Array[0..10] of Char; definieren und dann "sagen" EineStatischeMenge : TEineStatischeMenge;. Den Typ TEineStatischeMenge, nennt man ein statisches Array, da immer Speicherplatz fuer genau 11 !! Elemente (0..10) bereitstellt (reserviert). Wenn Du allerdings vorher nich genau weisst, wie gross Deine Menge sein soll oder wird, geht analog dazu TEineDynamischeMenge : Array of Char;. Deine Variable koennte dann EineDynamischesMenge:TEineDynamischeMenge heissen. Wie oben: Den Typ TEineDynamischeMenge, nennt man ein dynamisches Array, da die Anzahl (der belegte Speicher) deiner Elemente dynamisch (deinen wuenschen entsprechend) vergoessert oder verkleinert werden kann. Das geht mit SetLength(EineDynamischeMenge,11); (Setze die Laenge von Variablenname auf 11 Elemente). Noch was zur Konvention (ungeschiebenes Gesetz). Eigene Typen sollte immer der Buchstaben T fuer Type vorangestellt werden, da dann andere Programmierer (auch wenn sie nur einen Auszug aus deinem Programm sehen) sofort wissen: "Ahhhh.. hier hat Er einen neuen Typen eigefuehrt." Natuerlich solltest Du dann auch die Typendeklaration mit angeben oder sog. Self-Explaining-Type-Declarations (Seblstbeschreibende Deklaration) verwenden. z.B. TArrayOf10Integers oder TDynArrayOfString. Hoffe, hat geholfen (falls Dich ein Lehrer ausquetscht). |
Re: Mehere Elemente eines Feldes löschen durch überschreiben
jaaa auf jedenfall.. vielen vielen dank das war wirklich sehr gut erklärt.. dann werd ich mir den quellcode nochmal genauer unter die lupe nehmen ;) thx!!!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz