Größenveränderbares 1- und 2-dimensionales Array
Übersicht

ShamanBetreff: Größenveränderbares 1- und 2-dimensionales Array |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich stelle hier zwei Klassen vor, die 1-, bzw. 2-dimensionale Arrays darstellen.
TArray1D und TArray2D. Diese Arrays sind größenveränderbar, erlauben negative Indizes (Offset Rechnung) und kann man in einer for each - Schleife durchlaufen. außerdem vollständig dokumentiert Erstmal der Code: 1-dimensionale Version: Code: [AUSKLAPPEN] Rem bbdoc: Interface for Enumerators EndRem Type TEnumerator Abstract Method HasNext:Int() Abstract Method NextObject:Object() Abstract EndType Rem bbdoc: Interface for iterable Objects EndRem Type TIterable Abstract Method ObjectEnumerator:TEnumerator() Abstract EndType Rem bbdoc: A one-dimensional array of Objects EndRem Type TArray1D Extends TIterable Field _array:Object[] Field _size:Int Field _off:Int Method New() Private EndMethod Rem bbdoc: Creates the one-dimensional Array returns: the array about: size is the startsize and <br> offset is the start offset (for negative indexes) EndRem Function Create:TArray1D(size:Int=32,offset:Int=0) Local a:TArray1D=New TArray1D a._array=a._array[..size] a._size=Size a._off=Offset Return a EndFunction Rem bbdoc: Sets a value about: if the index is out of range, 0 is returned, else 1 EndRem Method Set:Byte(x:Int,obj:Object) x:+_off If x<0 Or x>=_size Then Return 0 _array[x]=obj Return 1 End Method Rem bbdoc: Gets a value returns: if the index is out of range, null is returned, else the value EndRem Method Get:Object(x:Int) x:+_off If x<0 Or x>=_size Then Return Null Return _array[x] End Method Rem bbdoc: Resizes the array about: size is the new size, and offset the new offset <br> Example: <br> an array with size=10 and offset=-3: <br> min. index is at x=-3 , max. index is at x=6 EndRem Method Resize(size:Int,offset:Int) Local a:Object[] Local i:Int Local diff:Int If offset<>_off Or size<>_size Then 'Resize in x-Richtung diff=-(offset+_off) If diff<0 Then Throw("Array2D can only become bigger") If size<_size Then Throw("Array2D can only become bigger") a=a[..size] For i=0 Until _size a[i+diff]=_array[i] Next _array=a _off=offset _size=size EndIf End Method Rem bbdoc: Diese Methode ist dazu da, dass ein Array1D-Objekt in einer "EachIn"-Schleife genutzt werden kann. returns: Das Enumerator-Objekt, dass von der "EachIn"-Schleife genutzt wird. EndRem Method ObjectEnumerator:TArray1DEnum() Return TArray1DEnum.Create(Self) EndMethod End Type Rem bbdoc: Enumerator for TArray2D EndRem Type TArray1DEnum Extends TEnumerator Field _array1D:TArray1D Field _x:Int Function Create:TArray1DEnum(array1D:TArray1D) Local enum:TArray1DEnum=New TArray1DEnum enum._x=0 enum._array1D=array1D Return enum End Function Method HasNext:Int() If Self._x<_array1D._size Then Return True Return False End Method Method NextObject:Object() Local value:Object=_array1D._array[Self._x] Self._x:+1 Return value End Method End Type Und die 2-dimensionale Version: Code: [AUSKLAPPEN] Rem bbdoc: A two-dimensional array of Objects EndRem Type TArray2D Extends TIterable Field _array:TArray1D[] Field _size:Int Field _off:Int Method New() Private EndMethod Rem bbdoc: Creates the two-dimensional Array returns: the array about: size is the startsize and <br> offset is the start offset (for negative indexes) <br> in both directions each EndRem Function Create:TArray2D(sizeX:Int=32,sizeY:Int=32,offsetX:Int=0,offsetY:Int=0) Local a:TArray2D=New TArray2D a._array=a._array[..SizeX] a._size=sizeX a._off=offsetX Local i:Int For i=0 Until sizeX a._array[i]=TArray1D.Create(sizeY,offsetY) Next Return a EndFunction Rem bbdoc: Sets a value about: if the index is out of range, 0 is returned, else 1 EndRem Method Set:Byte(x:Int,y:Int,obj:Object) x:+_off If x<0 Or x>=_size Then Return 0 Return _array[x].Set(y,obj) Return 1 End Method Rem bbdoc: Gets a value returns: if the index is out of range, null is returned, else the value EndRem Method Get:Object(x:Int,y:Int) x:+_off If x<0 Or x>=_size Then Return Null Return _array[x].Get(y) End Method Rem bbdoc: Resizes the array about: size is the new size, and offset the new offset <br> in both directions each. <br> see #Resize EndRem Method Resize(sizeX:Int,sizeY:Int,offsetX:Int,offsetY:Int) Local a:TArray1D[] Local i:Int Local diff:Int 'Resize in x-Richtung diff=-(offsetX+_off) If diff<0 Then Throw("Array2D can only become bigger") If sizeX<_size Then Throw("Array2D can only become bigger") a=a[..sizeX] For i=0 Until _size _array[i].Resize(sizeY,offsetY) a[i+diff]=_array[i] Next _array=a _off=offsetX _size=sizeX End Method Rem bbdoc: Diese Methode ist dazu da, dass ein Array2D-Objekt in einer "EachIn"-Schleife genutzt werden kann. returns: Das Enumerator-Objekt, dass von der "EachIn"-Schleife genutzt wird. EndRem Method ObjectEnumerator:TArray2DEnum() Return TArray2DEnum.Create(Self) EndMethod End Type Rem bbdoc: Enumerator for TArray2D EndRem Type TArray2DEnum Extends TEnumerator Field _array2D:TArray2D Field _x:Int Field _a1DEnum:TArray1DEnum Function Create:TArray2DEnum(array2D:TArray2D) Local enum:TArray2DEnum=New TArray2DEnum enum._x=0 enum._array2D=array2D enum._a1DEnum=array2D._array[0].ObjectEnumerator() Return enum End Function Method HasNext:Int() If Self._x<_array2D._size-1 Then Return True If Self._x<_array2D._size Then If Self._a1DEnum Then Return Self._a1DEnum.HasNext() Else Return False EndIf EndIf Return False End Method Method NextObject:Object() If Self._a1DEnum.HasNext()=True Then Return Self._a1DEnum.NextObject() Else Self._x:+1 Self._a1DEnum = _array2D._array[Self._x].ObjectEnumerator() Return _a1DEnum.NextObject() EndIf End Method End Type Zur Verwendung: Code: [AUSKLAPPEN] Local a:TArray2D=TArray2D.Create(5,8,2,3) ' Erstellt ein zwei-dim. Array mit x-Breite 5 und y-Höhe 8. Es fängt bei -2 bzw. -3 an a.Set(-2,-3,"kleinster index") a.Set(2,4,"größter index") a.Set(0,0,"test") Print String(a.Get(0,0)) ' --> "test" a.Resize(10,11,2,3) ' 5 spalten und 3 zeilen ans Ende angehängt, offset bleibt gleich. a.Set(7,7,"größter index") 'Iterator - Test (2-dimensional als Beispiel) local b:TArray2D=TArray2D.Create(5,5,0,0) local x:int,y:int For x=0 to 4 For y=0 to 4 b.Set(x,y,String(x+","+y)) Next Next 'Iteration: Local str:String For str = eachin b Print str Next Bei Fragen bitte melden. P.S. Code zum verkleinern des Arrays ist noch nicht vollständig, wenn jemand ihn schreibt freuts mich |
||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Verstehe ich nicht ganz. Normale Arrays sind doch auch in der Größe veränderbar können mit einer for-eachin Schleife durchlaufen werden, nicht?
BlitzMax: [AUSKLAPPEN] ' aus der BlitzMax-Hilfe: Ich meine, negative Indizes sind sicher auch ein gutes Feature, aber dafür ein Modul einbinden ist auch etwas unnötig. Kann man eventuell die Standardmodule so verändern, dass das funktionieren würde? Das fände ich sinnvoller. mfg Thunder |
||
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit |
![]() |
Der Eisvogel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Und was machst du bei Zweidimensionalen Arrays? Das geht mit BM nicht von Haus aus. ![]() |
||
Ungarische Notation kann nützlich sein.
BlitzMax ; Blitz3D Win 7 Pro 64 Bit ; Intel Core i7-860 ; 8 GB Ram ; ATI HD 5750 1 GB Projekte: Window-Crasher Ich liebe es mit der WinAPI zu spielen. |
dont_know_to_use |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Seit Wann sind denn Arrays größenveränderbar Thunder? BlitzBasic und -Max beherrschen keine dynamnischen Arrays. ![]() |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
dont_know_to_use: BMax beherrscht Slices, was im Prinzip Nichts anderes ist ![]() |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
Shaman |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das besondere ist ja, dass es 2-dimensional ist.
Es kann auch leicht auf 3-dimensional und so weiter erweitert werden. |
||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ok, die Sache mit der zweidimensionalen Version konnte ich nicht widerlegen. Ich dachte das funktioniert mit Array of Array, aber das scheint bei mir nicht zu klappen, Verzeihung.
Dennoch ist es ein bisschen ... inkonsistent... wenn ich für jede Dimension einen eigenen Arraytypen brauche. Abgesehen davon, dass ich überhaupt einen Arraytypen brauche und nicht ein Array, wie es der Compiler bereitstellt, habe. Und genau darauf habe ich mich bezogen, vorher, weil ich denke, dass der BlitzMax-Compiler vielleicht einem Programmierer etwas Spielraum lässt in TEnumerator o.Ä. rumzuspielen, aber ich war/bin mir da nicht sicher. und dont_know_to_use, auch wenn Holzchopf schon geantwortet hat: Ich habe nicht nur gesagt, das BlitzMax das (in der eindimensionalen Fassung) kann, sondern auch Code gepostet. Ich habe bis dato gedacht, meine Antwort sei idiotensicher. Im Endeffekt hat sich eh herausgestellt, dass eine Vermutung falsch war (siehe Anfang dieses Posts), aber der Code war richtig und er hat demonstriert wie ein eindimensionales Array in der Größe verändert und mit for-eachin durchlaufen wird. |
||
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit |
n-Halbleiter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Öhm, man kann auch Arrays of Arrays in ihrer Größe verändern, man muss nur immer in einer For-Schleife alle Elemente eines Arrays durchgehen. Ist zwar etwas unhandlich (unhandlicher als dein Code, Shaman, das wohl), allerdings dürfte es performanter sein, da einige Objekte mehr für deine Types benötigt werden. Und, was - denke ich - auch noch gegen deine Types spricht: Sie sind nicht auf einen Typ spezialisiert (was man jetzt sowohl als Vor-, als auch als Nachteil sehen kann), was bedeutet, dass man immer Casten muss; ist bei regulären Arrays nicht zwangsläufig der Fall. Und sie beherrschen keine Primitives, man müsste also, wenn man Integer speichern will, sie als String speichern und dann wieder zu Int (-> langsam)..
BlitzMax: [AUSKLAPPEN] SuperStrict |
||
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit Ploing! Blog "Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935) |
Shaman |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zu dem Problem, dass man immer casten muss:
Blitzmax beherrscht leider keine templates. (Oder irre ich mich da?) |
||
n-Halbleiter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Du hast schon recht, BMax beherrscht keine Templates. Und genau aus diesem und den anderen o.g. Gründen denke ich, dass dein Code nicht sonderlich sinnvoll ist; das Einzige, das er bringt, ist eine Verschleierung der Arrays und damit eine Vereinfachung der nutzenden Codes.
Das sind meine zwei Cents, wenn du anderer Meinung bist, ich bin ganz Ohr. ![]() |
||
mfg, Calvin
Maschine: Intel Core2 Duo E6750, 4GB DDR2-Ram, ATI Radeon HD4850, Win 7 x64 und Ubuntu 12.04 64-Bit Ploing! Blog "Die Seele einer jeden Ordnung ist ein großer Papierkorb." - Kurt Tucholsky (09.01.1890 - 21.12.1935) |
Shaman |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Du hast recht.
Ich hab den Code auch nur zur vereinfachung geschrieben. und aus faulheit, den Code yur groessenveraenderung immer wieder neu zu schreiben. |
||
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Schnell ist das aber nicht... | ||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
Shaman |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
inwiefern nicht schnell? | ||
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Im Sinne von Rechenleistung / Ergebnis. Durch solchen Overhead für einfachste Aufgaben verschwendet man viel mehr Leistung als wenn man sich einfach kurz hinsetzt und den Arrayzugriff selbst berechnet. Gerade Arrays benutze ich vor allem dann, wenn es sehr zeitkritisch ist. | ||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group