PDA

View Full Version : [Java] clonare array multiplo


fero86
03-03-2010, 13:29
salve. ho un array che ha la bellezza di 4 (quattro :asd: ) dimensioni :asd:
e come se non bastasse vorrei addirittura clonarlo :sofico:

l'array é un array di enum, orientativamente la struttura é questa:
enum MyEnum { ONE, TWO, THREE, FOUR, };
...

MyEnum[][][][] array = { ... };
l'array é completamente inizializzato. volevo sapere se esiste un sistema comodo per clonarlo, dove l'espressione "clonarlo" ha per me il solo ed unico requisito essenziale che le modifiche sul clone non abbiano effetto sull'originale. quindi voglio poter fare una cosa del genere:
MyEnum[][][][] array2 = array.clone();
array[0][0][0][0] = ONE;
array2[0][0][0][0] = TWO;
assert array[0][0][0][0] == ONE;
assert array2[0][0][0][0] == TWO;

ho la netta sensazione che il metodo clone() non vada bene, erro? esiste un sistema comodo, senza dover annidare 4 for?

PS: comunque tranquilli, complessivamente l'array contiene solamente 162 elementi (3*3*3*6) :D

wingman87
03-03-2010, 13:47
Potresti scrivere 4 metodi clone ognuno dei quali prende in input un array a n dimensioni con n da 1 a 4. Quello che prende un array a 4 dimensioni richiama il metodo che prende un array a 3 che richiama quello da 2 che richiama quello da 1. Così da un lato è semplice scrivere i metodi e dall'altro puoi riutilizzarli qualora ti servissero dei metodi clone per array a n dimensioni con n non necessariamente 4.

yorkeiser
03-03-2010, 14:01
ho la netta sensazione che il metodo clone() non vada bene, erro?
Sul multidimensionale mi pare proprio di no (a meno ovviamente di riscrivere il metodo).

esiste un sistema comodo, senza dover annidare 4 for?
Curisosità personale: cosa c'è di scomodo nell'annidare 4 for - manco ti servono le graffe - ?

PGI-Bis
03-03-2010, 14:08
Puoi clonare un array di array ma il risultato è una copia della radice che condivide i componenti dal secondo livello in poi (cioè non serve a una cippa).

Usa i for.

Ps.: un array di array di array di array è una vera schifezza.

fero86
04-03-2010, 13:13
grazie per le risposte, si alla fine ho usato i for e tanti saluti.

PGI, lo so che é una schifezza ma tu come rappresenteresti in memoria un cubo di Rubik? :stordita: :D

ndakota
04-03-2010, 13:19
PGI, lo so che é una schifezza ma tu come rappresenteresti in memoria un cubo di Rubik? :stordita: :D

E la quarta dimensione per cosa sta?

Edit: provo a rispondermi da solo: i colori?

banryu79
04-03-2010, 13:25
grazie per le risposte, si alla fine ho usato i for e tanti saluti.

PGI, lo so che é una schifezza ma tu come rappresenteresti in memoria un cubo di Rubik? :stordita: :D
Potrei dire cavolate, ma potresti "srotolare" tutto in un "semplice" array di 27 elementi di tipo java.awt.Color che wrappi in una classe che rappresenta il cubo di Rubik e che espone metodi per manipolarlo; i dettagli implementativi del cubo non vengono esposti all'esterno.
Non essendomi mai cimentato con i cubi di Rubik non so se la proposta sia sensata o meno.

PGI-Bis
04-03-2010, 13:38
PGI, lo so che é una schifezza ma tu come rappresenteresti in memoria un cubo di Rubik? :stordita: :D

Prova con una mappa o una funzione di indicizzazione su un array ad una dimensione.

In ogni caso nascondi tutto sotto il tappeto di un oggetto ma immagino che tu abbia già la tua classettina CuboDiRubik.

banryu79
05-03-2010, 10:38
Ehi fero, non so se ti può interessare, ma questo sito è una miniera di informazioni circa la soluzione del cubo di Rubik e presenta delle tecniche visivamente tramite applet carine con cubi in 3D.
Magari ti ispira, tiè: http://lar5.com/cube/

fero86
06-03-2010, 13:43
E la quarta dimensione per cosa sta?
Edit: provo a rispondermi da solo: i colori? esatto: come ho giá scritto l'array é da 3*3*3*6, l'ultima dimensione é per i colori, 6 per ogni cubetto, anche se in realtá ogni cubetto non espone tutte e 6 le facce: ce ne sono alcuni che ne espongono 3, alcuni che ne espongono 2 e alcuni che ne espongono una sola, ma per semplicitá implementativa ho fatto cosi.



Potrei dire cavolate, ma potresti "srotolare" tutto in un "semplice" array di 27 elementi di tipo java.awt.Color che wrappi in una classe che rappresenta il cubo di Rubik e che espone metodi per manipolarlo; i dettagli implementativi del cubo non vengono esposti all'esterno.
Non essendomi mai cimentato con i cubi di Rubik non so se la proposta sia sensata o meno.
Prova con una mappa o una funzione di indicizzazione su un array ad una dimensione. memorizzarlo in un array da 27*6 a cui accedere con una funzione di indicizzazione (che calcola l'indice di un cubetto dati i suoi tre indici nel cubo) non é una cattiva idea, ma non vedo perché farlo visto che la cosa non fa altro che complicare il codice: le cataste di for annidati per implementare i vari algoritmi comunque rimangono, e in piu devo anche implementare la funzione di indicizzazione.



Ehi fero, non so se ti può interessare, ma questo sito è una miniera di informazioni circa la soluzione del cubo di Rubik e presenta delle tecniche visivamente tramite applet carine con cubi in 3D.
Magari ti ispira, tiè: http://lar5.com/cube/ grazie, infatti mi interessa! :D
so giá risolvere il cubo di Rubik ma uso una tecnica molto lenta (richiede parecchie mosse), mi divertirebbe molto impararne una piu veloce! :)

fero86
06-03-2010, 13:44
se vi interessa, per ora la classe che rappresenta il cubo é fatta cosi:
public final class Cube {
private static boolean isInternal(int i, int j, int k, int l) {
Face face = Face.values()[l];
switch (face) {
case GREEN:
if (i != 0) {
return true;
}
break;
case YELLOW:
if (j != 2) {
return true;
}
break;
case RED:
if (k != 2) {
return true;
}
break;
case ORANGE:
if (k != 0) {
return true;
}
break;
case BLUE:
if (j != 0) {
return true;
}
break;
case WHITE:
if (i != 2) {
return true;
}
break;
}
return false;
}

/**
* Array tridimensionale di cubetti; ogni cubetto e' un array di 6 facce.
* THIS... IS... RUBIIIK!!!
*/
public Face[][][][] faces = new Face[3][3][3][6];
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 6; l++) {
if (isInternal(i, j, k, l)) {
faces[i][j][k][l] = Face.INTERNAL;
} else {
faces[i][j][k][l] = Face.values()[l];
}
}
}
}
}
}

private Face[][][][] duplicateCube() {
Face[][][][] newCube = new Face[3][3][3][6];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 6; l++) {
newCube[i][j][k][l] = faces[i][j][k][l];
}
}
}
}
return newCube;
}

public void rotateY(int tier, boolean clockwise) {
Face[][][][] newCube = duplicateCube();

if (clockwise) {
final int[] facePermutation = { 0, 3, 1, 4, 2, 5, };
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 6; l++) {
newCube[tier][k][2 - j][facePermutation[l]] = faces[tier][j][k][l];
}
}
}
} else {
final int[] facePermutation = { 0, 2, 4, 1, 3, 5, };
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 6; l++) {
newCube[tier][2 - k][j][facePermutation[l]] = faces[tier][j][k][l];
}
}
}
}

faces = newCube;
}

public void rotateZ(int tier, boolean clockwise) {
Face[][][][] newCube = duplicateCube();

if (clockwise) {
final int[] facePermutation = { 2, 1, 5, 0, 4, 3, };
for (int i = 0; i < 3; i++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 6; l++) {
newCube[k][tier][2 - i][facePermutation[l]] = faces[i][tier][k][l];
}
}
}
} else {
final int[] facePermutation = { 3, 1, 0, 5, 4, 2, };
for (int i = 0; i < 3; i++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 6; l++) {
newCube[2 - k][tier][i][facePermutation[l]] = faces[i][tier][k][l];
}
}
}
}

faces = newCube;
}

public void rotateX(int tier, boolean clockwise) {
Face[][][][] newCube = duplicateCube();

if (clockwise) {
final int[] facePermutation = { 4, 0, 2, 3, 5, 1, };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int l = 0; l < 6; l++) {
newCube[2 - j][i][tier][facePermutation[l]] = faces[i][j][tier][l];
}
}
}
} else {
final int[] facePermutation = { 1, 5, 2, 3, 0, 4, };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int l = 0; l < 6; l++) {
newCube[j][2 - i][tier][facePermutation[l]] = faces[i][j][tier][l];
}
}
}
}

faces = newCube;
}

public boolean done() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (faces[0][i][j][0] != Face.GREEN) {
return false;
}
if (faces[i][2][j][1] != Face.YELLOW) {
return false;
}
if (faces[i][j][2][2] != Face.RED) {
return false;
}
if (faces[i][j][0][3] != Face.ORANGE) {
return false;
}
if (faces[i][0][j][4] != Face.BLUE) {
return false;
}
if (faces[2][i][j][5] != Face.WHITE) {
return false;
}
}
}
return true;
}
}



questo é il tipo Face:
public enum Face {
GREEN, YELLOW, RED, ORANGE, BLUE, WHITE, INTERNAL,
}