Wie ermittelt man am besten die Größe eines Sets oder die Anzahl an Elementen in einem Set?
Es geht um ein Set, welches maximal 7 Elemente aufnehmen kann. Als Bytewert ergibt das am Ende 127. Ich könnte gegen diese 127 prüfen aber es muss doch eine Möglichkeit geben zu ermitteln, wieviele Elemente in diesem Set sind oder nicht?
Die Größe eines Sets, in Bytes, liefert die gute alte Sizeof-Funktion. Um die Zahl der Elemente zu ermitteln, die der Set aktuell enthält, muss man sie allerdings zählen, da führt kein Weg dran vorbei. Der einfachste Ansatz ist sowas wie:
Delphi-Quellcode:
type
TSetElement = (liste von identifiern);
TElementSet = set of TSetElement;
function CountOfElements(const aSet: TElementSet ): integer;
var
I: TSetElement;
begin
Result := 0;
for I:= Low(I) to High(I) do
if I in aSet then
Inc(Result);
end;
Vorteil: das ist völlig unabhängig von der Art, in der Sets implementiert sind.
Nachteil: es ist spezifisch für einen bestimmten typ von set und relativ CPU-intensiv.
Wenn man keine Skrupel hat, Kenntnis über die Art der Implementierung zu verwenden, ist es einfach, eine generelle Funktion zu schreiben, die für alle Arten von Sets funktioniert. Ein Set in Delphi ist einfach ein array of byte, und jedes gesetzte Bit repräsentiert ein im Set enthaltenes Element.
Delphi-Quellcode:
function BitCount(
var aValue; size: Word): Integer;
type
{$Z-}
Bitset =
set of 0..7;
var
proxy:
array[0..High(Word) - 1]
of Bitset
absolute aValue;
n: Integer;
begin
Assert(Sizeof(Bitset) = 1);
Result := 0;
if Size = 0
then Exit;
Dec(size);
while true
do begin
if proxy[size] <> []
then
for n := 0
to 7
do begin
if n
in proxy[size]
then
Inc(Result);
end;
{ For }
if size = 0
then
Break;
Dec(size);
end;
{ While }
end;
Aufruf:
LSetSize:= BitCount(aSet, Sizeof(aSet));
Das kann man noch weiter optimieren, indem man anstelle der for-Schleife einen array [byte] of integer verwendet, der für jeden möglichen Wert eines Bytes die Zahl der gesetzten Bits enthält.