Mehrdimensionales Array: Inhalt innerhalb des Arrays verschieben



  • Hallo an alle,
    hab’ gerade Euer Forum gefunden und mich mal angemeldet. 🙂

    Natürlich habe ich auch direkt eine Frage:
    Ich habe ein mehrdimensionales Array (drei Dimensionen, also array[x][y][z]) mit der Größe von [11][6][2]. Ich möchte nun unter Umständen den Inhalt des Arrays in einer Dimension um ein Element verschieben. Das Element array[5][5][1] soll sich also zum Beispiel nach der Verschiebung in der X-Achse als Element array[4][5][1] wiederfinden oder nach der Verschiebung in der Y-Achse als Element array[5][4][1]. Verschiebungen in der Z-Achse müssen normalerweise nicht durchgeführt werden. Das Array ist nicht dynamisch, sondern hat wie gesagt eine feste Größe! Es wird nur verschoben und damit eine Spalte bzw. Zeile überschrieben, wenn diese leer ist. Ich hoffe, ihr habt das Problem bzw. die Fragestellung verstanden.
    Dazu habe ich diverse Lösungsansätze gefunden: Ein eher suboptimaler Ansatz wäre eine Zählschleife, die das ganze Array durchgeht und das in einen Buffer kopiert, von dem es wieder zurückkopiert wird... Sehr unschön, vor allem sehr langsam (das Ganze soll auf einem auf 16MHz getakteten 8bit Mikrocontroller von Atmel laufen). Eine weitere Möglichkeit ist der Einsatz von Pointern. Dazu habe ich diesen Thread in diesem Forum gefunden. Ich habe mich noch nicht intensiv mit Pointern beschäftigt, grundsätzlich verstehe ich die Anwendung aber. Schwierig wird es nur mit mehrdimensionalen Arrays und wahrscheinlich dann auch nötigen mehrdimensionalen Pointern.
    Wie könnte der Ansatz da aussehen? Hab’ leider gar keine Idee, wie man das möglichst effektiv umsetzen könnte...
    Viele Grüße
    Jan

    EDIT:
    Muss ergänzen, dass es nicht direkt ein Array ist, sondern eine Datenstruktur, die so aufgebaut ist:

    struct lab {
    	int8_t wall_s;
    	int8_t wall_w;
    	int8_t ground;
    	uint8_t tarry;
    } maze[MAZE_SIZE_X][MAZE_SIZE_Y][MAZE_SIZE_Z];
    

    Ändert das etwas an der Vorgehensweise?


  • Mod

    Sollen die Randbedingungen periodisch sein? Falls nein: Was passiert am Rand?

    Hier noch eine ganz andere Idee, auf die du anscheinend noch nicht gekommen bist:
    Lass das Geschiebe sein. Speicher dir einfach den Offset des Arrayzugriffes. Wenn du auf das Array zugreifst, rechnest du den Offset auf die Indizes dazu. Natürlich alles schön weggekapselt, damit nichts schiefgehen kann. Eine Verschiebung des Arrays ist einfach eine Verschiebung des Zugriffsoffsets.
    Diese Lösung verlangt überhaupt keinen Kopieraufwand, dafür etwas mehr Aufwand beim Zugriff. Dies dürfte in den meisten Fällen erheblich günstiger sein als eine tatsächliche Verschiebung der Daten, sofern das Verhältnis von Zugriffen zu Verschiebungen nicht sehr, sehr groß wird.
    In C++ wäre diese Lösung wunderschön umsetzbar, in C wird's teils ein bisschen eklig. Sollte dich aber nicht abschrecken angesichts der möglichen Vorteile.



  • Hi,
    was genau meinst Du mit Randbedingungen?
    Die Idee mit dem Offset finde ich sehr gut! Danke. 🙂 Das scheint mir auch gar nicht so kompliziert, man braucht ja nur für jede Dimension eine Variable für den Offset. Funktionen, mit denen ich auf die einzelnen Variablen der Datenstruktur zugreife, habe ich so oder so, da kann man dann auch den Offset mit einbauen (einfach auf den Index der Dimension rechnen und wenn es über oder unter der definierten Größe liegt die Größe vom Offset subtrahieren).
    Was exakt meinst Du mit Weggekapselt? Sorry, ich komme nicht aus der C++ Programmierung (falls die Begriffe daher kommen 🙂 ) bzw. habe mich damit noch nicht intensiv beschäftigt. Eine kurze Erklärung oder ein Link dazu wäre nett (ich finde nur ausschließlich mathematische Erklärungen ohne Bezug zur Informatik).

    Grüße
    Jan


  • Mod

    Diphthong schrieb:

    was genau meinst Du mit Randbedingungen?

    Was passiert am Rand?

    Was exakt meinst Du mit Weggekapselt?

    Du packst alles in ein struct, das Array und die Offsets. Zugriff auf das Array erfolgt über spezielle Funktionen, die das Gesamtstruct benutzen und den Offset aufrechnen. Auf diese Weise musst du diese (relativ einfachen) Funktionen bloß ein einziges Mal richtig schreiben. Vor allem geht es darum, dass nicht jeder Benutzer des Arrays seinen eigenen Offsetcode schreibt. Dies vermeidet Fehler und erleichtert spätere Änderungen.


Anmelden zum Antworten