Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - p := Pointer(str)?!
Bergmann89 - Di 26.06.12 14:22
Titel: p := Pointer(str)?!
Hey,
ich schrieb mir grad ne generische Liste, die mit Keys anstatt mit Indizes arbeitet. Der Sinn der ganzen Sache ist, das ich zu einem Key einen Wert abspeichern kann und auch möglichst schnell darauf zugreifen kann. Dazu werden die Keys sortiert in die Liste eingefügt. Beim Zugriff kann ich dann ähnlich wie beim QuickSort-Algorithmus die Daten zum passenden Key suchen.
Ich weiß jetzt aber nicht recht wie ich den Key speichern soll. Bis jetzt caste ich den Key auf einen Pointer uns speicher den dann zwischen. aKey und aObject sind generics:
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:
| TKeyObjectListItem = packed record obj, key: Pointer; end; PKeyObjectListItem = ^TKeyObjectListItem;
function TKeyObjectList.InsertItem(const aMin, aMax: Integer; const aKey: K; const aObject: T): Integer; var i, compare: Integer; p: PKeyObjectListItem; begin if aMin <= aMax then begin i := aMin + Trunc((aMax - aMin) / 2); compare := CompareKeys(aKey, K(PKeyObjectListItem(fList[i])^.key)); if (compare = 0) then begin raise EKeyObjectList.Create('key already in list'); end else if (compare < 0) then result := InsertItem(aMin, i-1, aKey, aObject) else if (compare > 0) then result := InsertItem(i+1, aMax, aKey, aObject); end else begin new(p); p^.obj := aObject; p^.key := Pointer(aKey); fList.Insert(aMin, p); result := aMin; end; end; |
Dann hab ich mir überlegt, was passiert wenn man als Schlüsseltyp Strings verwendet. Dann würde ich ja den String einfach auf einen Pointer casten und zwischenspeichern. Kann man das so machen, oder ist bei dieser Methode nicht gewährleistet, das der String richtig gespeichert wird? Als Alternative würde ich das dann so machen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| new(p); p^.obj := aObject; new(^K(p^.key)); (^K(p^.key))^ := aKey; fList.Insert(aMin, p); result := aMin; |
Sieht ziemlich verwirrend aus :? Aber eig sollte das gehen^^ Welche der beiden Wege ist nun der bessere?! Oder sind beide Müll und es gibt einen dritten?!
MfG Bergmann.
jaenicke - Di 26.06.12 14:44
Wenn du ohnehin Generics benutzt, was spricht dann gegen ein normales (automatisch mit Hashes arbeitendes) TDictionary (aus der Unit Generics.Collections)?
Bergmann89 - Di 26.06.12 14:47
Hey,
ich entwickle mich Lazarus, da hab ich bis jetzt noch nix gefunden, was mir gefällt, oder was ohne Fehler funktioniert. Also hab ich da ma fix was selber gezaubert^^
MfG Bergmann.
jaenicke - Di 26.06.12 15:37
Ach ja, stimmt, da gibts ja auch ein bisschen Generics.
Ein Cast eines Strings wird jedenfalls schief gehen (der geht übrigens auch mit PChar(DeinString)), da der String am Ende des Scopes (also der Methode in diesem Fall) freigegeben wird. Danach nutzt dir der Pointer nichts mehr.
Warum machst du den Record nicht einfach auch generisch? Dann hast du das ganze Problem nicht mehr, weil du auch den String direkt reinpacken kannst. In Delphi gibt es für zwei Werte TPair<T,K> als vordefinierten generischen Record.
Bergmann89 - Di 26.06.12 16:00
"bisschen" triffts gut ^^
generische Record gibt es leider (noch) nicht. Aber ich hab festgestellt, das ich das Record auch in der Klasse definieren kann. Wusste gar nich, dass das geht^^
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| type generic TKeyObjectList<T, K> = class(TObject)
type TKeyObjectListItem = packed record obj: T; key: K; end; PKeyObjectListItem = ^TKeyObjectListItem;
private fList: TList; |
So gehts wunderbar. Danke für die schnelle Hilfe :)
MfG Bergmann.
jaenicke - Di 26.06.12 16:46
Nur als Anmerkung für spätere Leser: Das Einbetten von Typen in andere Typen geht in Delphi seit Version 2006 genauso, das nennt sich nested types.
(Unterschied ist nur, dass man nicht "generic" vor die TKeyObjectList schreiben muss, das erkennt Delphi auch so.)
delfiphan - Di 26.06.12 20:10
jaenicke hat folgendes geschrieben : |
übrigens auch mit PChar(DeinString) |
wobei anzumerken ist, dass PChar(...) und Pointer(...) nicht äquivalent sind.
Kha - Di 26.06.12 20:47
Bergmann89 hat folgendes geschrieben : |
Dazu werden die Keys sortiert in die Liste eingefügt. |
So ist Einfügen immer noch in linearer Zeit, warum kein binärer Suchbaum?
Bergmann89 hat folgendes geschrieben : |
Beim Zugriff kann ich dann ähnlich wie beim QuickSort-Algorithmus die Daten zum passenden Key suchen. |
Aka binäre Suche ;) .
Bergmann89 - Di 26.06.12 21:26
Hey,
Suchbaum wäre auch ne Idee, aber ich muss die Daten auch relativ oft komplett durchlaufen und da hab ich lieber ne einfache Schleife, als ne Tiefen-/Breitensuche und ein Callback. So wie ich das jetzt mach ist es dem Algorithmus vom Binärbaum ja relativ ähnlich, nur die Datenstruktur ist halt linear. Das Einfügen ist nicht linear (siehe Code im ersten Post). Ich denke auch, das es so oder als Binärbaum in der Geschwindigkeit keine großen Änderungen mehr geben wird.
MfG Bergmann.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!