Spielerei: BitArray für Nullen und Einsen
Verfasst: 30.01.2007 12:49
Für alle, die etwas Speicherplatz sparen wollen und wenn es nur um Einsen
oder Nullen geht:
Und hier noch ein Beispielcode für Primzahlen. Erkennt bei mir in 26
Sekunden alle Primzahlen zwischen 0 und 134.217.728.
Viel Spaß damit! 
Wenn es Optimierungen gibt, her damit!
oder Nullen geht:
Code: Alles auswählen
;Info: BitArray
Procedure DimBitArray(Size.l) ;Allokiert den Speicher für ein neues Array, Result: Pointer
Size + 1
If Size > 0
If Size & 7
ProcedureReturn AllocateMemory(Size >> 3 + 1)
Else
ProcedureReturn AllocateMemory(Size >> 3)
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure ReDimBitArray(Size.l, *Array) ;Ändert die Größe eines Arrays, Result: Neuer Pointer
Size + 1
If Size > 0
If Size & 7
ProcedureReturn ReAllocateMemory(*Array, Size >> 3 + 1)
Else
ProcedureReturn ReAllocateMemory(*Array, Size >> 3)
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure FreeBitArray(*Array) ;Gibt den Speicher wieder frei
If *Array
FreeMemory(*Array)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Macro SwapBit(Array, Bit) ;Wechselt den Zustand eines Bits zwischen 0 und 1
PokeB(Array + Bit >> 3, PeekB(Array + Bit >> 3) ! (1 << (Bit & 7)))
EndMacro
Macro GetBit(Array, Bit) ;Gibt ein Bit zurück
((PeekB(Array + Bit >> 3) >> (Bit & 7)) & 1)
EndMacro
Macro SetBit(Array, Bit, state) ;Setzt ein Bit (nur 0 oder 1 benutzen!)
PokeB(Array + Bit >> 3, (PeekB(Array + Bit >> 3) & ~(1 << (Bit & 7))) | (state << (Bit & 7)))
EndMacro
Sekunden alle Primzahlen zwischen 0 und 134.217.728.
Code: Alles auswählen
Define MaxPrim.l, *prim, time.l, i.l, start.l, a.l
MaxPrim = 1024 * 1024 * 128
*prim = DimBitArray(MaxPrim) ;Allokiert 16 MB
time = ElapsedMilliseconds()
start = 2 ;erste Primzahl
While start < MaxPrim
Debug start ;gib primzahl aus
i = start * 2
While i < MaxPrim ;Markiere alle Vielfache von start
SetBit(*prim, i, 1)
i + start
Wend
Repeat ;Suche nächste Primzahl
start + 1
Until GetBit(*prim, start) = 0
Wend
time = ElapsedMilliseconds() - time
MessageRequester("Zeit", "Zeit für alle Primzahlen zwischen 0 und " + Str(MaxPrim) + ":" + Chr(13) + Str(time) + " ms")
;0 und 1 sind keine Primzahlen
For a = 2 To MaxPrim - 1
If GetBit(*prim, a) = 0 ;Alle, die nicht markiert sind, sind Primzahlen
Debug a
EndIf
Next
FreeBitArray(*prim) ;Gibt Speicher wieder frei

Wenn es Optimierungen gibt, her damit!