![]() |
Sets durchlaufen
Hallo,
Ich habe ein Set of Char und möchte nun für jedes Element in dem Set etwas tun. Die lauffähige und langsame Variante sieht so aus:
Delphi-Quellcode:
Effizienter wäre es natürlich, wenn man gar nicht erst jedes irgend mögliche Element auf Zugehörigkeit zum Set prüfen müsste, sondern gleich direkt das Set durchlaufen würde. Intern liegt dem Set ja ein ordinaler Typ zugrunde, der eine Ordnung hat. Diese Ordnung könnte man theoretisch dazu nutzen, um ein Element nach dem anderen zu durchlaufen. Aber wahrscheinlich ist diese Möglichkeit unerwünscht, da sie sich nicht an die Semantik eines Sets als Menge ohne Ordnung hält.
for c := Low(Char) to High(Char) do
if c in MyCharSet then Tuewas(c); |
Re: Sets durchlaufen
Zitat:
Ein set kann doch eh nur 256 Elemente beinhalten - so langsam kann das doch nicht sein? Und nein, sowas wie du es dir vorstellt gibt es imho nicht - ein Set besteht ja auch nur aus 8 Byte, in denen für jedes Element ein Bit angibt, ob es drin ist oder nicht. Die Bits da rauszuwurschteln dürfte auch wieder darauf hinauslaufen, dass man alle durchgeht und prüft ob sie drin sind. Was natürlich geht, ist: Du machst dir eine Liste, in der alle Elemente drin sind, die auch im Set drin sind. |
Re: Sets durchlaufen
Ein SET hat intern keinen Ordinalen Type ... ein SET ist eine Reihe von Bits.
Der ENUM (die Elemente des SETs) sind ordinalen Typs. Zitat:
Ja, es gäbe (wenn das SET nicht zu voll ist) eine kleine Optimierungsmöglichkeit, aber bei nur 256 Werten bringt das fast garnichts, da diese 256 Möglichkeiten alleine schon sehr schnell durchgelaufen sind. (Bei meinem größeren WideCharSet sah das schon anders aus, denn da gibt es schon über 65.000 Möglichkeiten, wo sich soeine Optimierung schon eher anbot.) PS: in neueren Delphis ginge auch sowas,
Delphi-Quellcode:
welches theoretisch deiner FOR+IF-Schleife entspricht.
for c in MyCharSet do
Zitat:
|
Re: Sets durchlaufen
Zitat:
|
Re: Sets durchlaufen
Zitat:
Zitat:
Zitat:
Ich werde mich einfach mit meiner doch nocht so langsamen Lösung begnügen :zwinker: |
Re: Sets durchlaufen
Zitat:
Bis Delphi 2007 ist ein Set of Char ein Set of AnsiChar und ab Delphi 2009 wäre es ein Set of WideChar, welches allerdings nicht geht. Eben wegen der 256er Byte-Grenze. Die Adressierung der Bits wird direkt über einen Assembler-Befehl vorgenommen, und dieser unterstützt nur eine ByteAdresse. Darum auch so umständliche CharSet-Ersätze, wie z.B. ![]() |
Re: Sets durchlaufen
Von welchem Typ ist dann eigentlich ['a', 'ß', '0']? Geht das ab D2009 auch nicht mehr? Dann würde ich das komplett umbauen... Ich hab auch im Moment einen sehr eigenartigen Fehler:
Delphi-Quellcode:
TKeys = record
Keys: set of Char; end; TNeu = class private FKeys: TKeys; published property MyKeys: TKeys read FKeys write FKeys; end; Neu.MyKeys.Keys := [] // Fehler: Der linken Seite kann nichts zugewiesen werden |
Re: Sets durchlaufen
Fehlt da nicht ein "property" vor 'MyKeys'? :gruebel:
|
Re: Sets durchlaufen
Sorry, Tippfehler, das steht im Origionalquelltext natürlich drin ;-) fixed
|
Re: Sets durchlaufen
Zitat:
['a', 'ß', '0'] bleibt unter Delphi 2009/2010 ein AnsiCharSet, bzw. es gibt einen Typen dafür ![]() Der ShortString, String[x] und das CharSet bleiben also weiterhin nur ANSI. (darum auch der in Beitrag #6 verlinkte Code) Zitat:
Dieses Verhalten wird auch immer mal wieder hier im Forum genannt. Es wird entweder eine Getter oder eine Setter aufgerufen. Neu.MyKeys.xxx ruft den Getter auf, damit weiter auf .Keys zugegriffen werden kann.
Delphi-Quellcode:
Tja, und nun rate mal, was mit dem zugewiesenem Wert passiert?
Neu.MyKeys.Keys := [];
// wird also zu DemphiinterneTemporäreVariable := Neu.MyKeys; // bzw. Neu.GetMyKeys DemphiinterneTemporäreVariable.Keys := []; Genau ... nix, denn die TempVar wird irgendwann wieder gelöscht und im Property ändert sich nix. Und darum warnt jetzt Delphi davor. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:48 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