2014-06-27 4 views
6

Supponiamo di disporre di una matrice multidimensionale e il numero di dimensioni è noto solo in fase di esecuzione. E supponiamo di avere un numero intero di indici.Come accedere a un array multidimensionale a livello di codice in Java?

Come applicare gli indici all'array per accedere all'elemento dell'array?

UPDATE

Supponiamo:

int [] indices = new int { 2, 7, 3, ... , 4}; // indices of some element 
int X = indices.length; // number of dimensions 
Object array = .... // multidimensional array with number of dimensions X 

... 

voglio prendere dell'elemento indirizzato dagli indici indices da array.

UPDATE 2

Ho scritto seguente codice sulla base di ricorsione: ci

1) sono metodi già pronti affidabili da JDK e/o:

package tests; 

import java.util.Arrays; 

public class Try_Multidimensional { 

    private static int element; 

    public static int[] tail(int[] indices) { 
     return Arrays.copyOfRange(indices, 1, indices.length); 
    } 


    public static Object[] createArray(int ... sizes) { 

     Object[] ans = new Object[sizes[0]]; 

     if(sizes.length == 1) { 
      for(int i=0; i<ans.length; ++i) { 
       ans[i] = element++; 
      } 
     } 

     else { 
      for(int i=0; i<ans.length; ++i) { 
       ans[i] = createArray(tail(sizes)); 
      } 
     } 

     return ans; 

    } 

    public static Object accessElement(Object object, int ... indices) { 

     if(object instanceof Object[]) { 

      Object[] array = (Object[]) object; 

      return accessElement(array[indices[0]], tail(indices)); 

     } 

     else { 
      return object; 
     } 

    } 

    public static void main(String[] args) { 

     element = 0; 
     Object array = createArray(4, 5, 12, 7); 

     System.out.println(accessElement(array, 0, 0, 0, 0)); 
     System.out.println(accessElement(array, 0, 0, 0, 1)); 
     System.out.println(accessElement(array, 1, 0, 10, 0)); 
     try { 
      System.out.println(accessElement(array, 0, 5, 0, 1)); 
     } 
     catch(Exception e) { 
      System.out.println(e.toString()); 
     } 

    System.out.println(4*5*12*7-1); 
    System.out.println(accessElement(array, 3, 4, 11, 6)); 

    } 

} 

Le domande sono librerie famose per questo?

2) Stavo usando Object. può essere evitato? posso creare/accedere a un array di dimensionalità variabile di tipo built-in o specifico? quanto è grande il guadagno dovuto all'utilizzo di Object?

+4

Potrebbe essere un po 'più specifico per favore, magari fornire uno snipplet di codice? – TimStefanHauschildt

+0

Potete per favore fornire qualsiasi esempio. Capire – Kick

+0

Vi suggerisco di leggere [questo] (http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html). – Djon

risposta

2
int index(Object arrayToIndex, int... indices) { 
    for (int i = 0; i < indices.length - 1; i++) { 
     arrayToIndex = ((Object[]) arrayToIndex)[indices[i]]; 
    } 
    return ((int[]) arrayToIndex)[indices[indices.length-1]]; 
} 

Passare attraverso le dimensioni e indicizzare ogni dimensione, una alla volta. I cast e il caso speciale per l'ultima dimensione saranno fastidiosi, quindi consiglio di inserire questo in una sorta di classe array n-dimensionale. (It looks like some options already exist.)

+0

Penso che voglia creare una matrice con N dimensioni dove N non è noto fino al runtime, che la lingua non supporta. –

+0

@JeffScottBrown: la domanda parla solo dell'accesso all'array. La creazione è un'altra questione. – user2357112

+0

Ho frainteso la domanda nello stesso modo in cui hai fatto. La domanda include "Array di oggetti = .... // array multidimensionale con numero di dimensioni X" ed è il lato destro lì che è la cosa che non può essere fatta. Non è possibile creare un array con un numero dinamico di dimensioni, che è ciò che penso che lei sia dopo. Forse mi sbaglio su quello che lei sta cercando. –

0

è possibile scoprire la dimensione di ogni dimensione come singoli array (perché questo è quello che sono):

public void someMEthod(int[][][] matrix) { 
    int d1 = matrix.length; 
    int d2 = 0; 
    int d3 = 0; 
    if(d1 > 0) { 
     d2 = matrix[0].length; 
     if(d2 > 0) { 
      d3 = matrix[0][0].length; 
     } 
    } 
    System.out.println("Dimension 1 is " + d1); 
    System.out.println("Dimension 2 is " + d2); 
    System.out.println("Dimension 3 is " + d3); 
} 

Mi auguro che aiuta.

+0

Il numero di dimensioni è variabile, non solo la dimensione di ogni dimensione. – user2357112

+0

Suppongo che il problema qui sia che l'array ha un numero sconosciuto di dimensioni, quindi 'matrix' non può essere arbitrariamente dichiarato come un' int [] [] [] '. –

+0

La domanda originale è stata modificata in modo tale che non sono sicuro che questo risponda davvero a questa domanda. La risposta alla domanda così com'è attualmente scritta è che non puoi farlo. Quando viene dichiarata la matrice, è necessario conoscere il numero di dimensioni. I valori di ciascuna di queste dimensioni possono essere dinamici di runtime, ma non il numero di dimensioni. –

0

Ho trovato un modo un po 'divertente di farlo usando il riflesso. Questo è solo un codice che ho buttato insieme, ma potresti avvolgerlo in una classe e renderlo tutto molto carino.

// build and fill an array to the given depth 
public static Object[] constructArray(Object[] array, int depth) { 
    if(depth == 0) 
     return null; 

    for(int i=0;i<array.length;i++) { 
     Array.set(array, i, constructArray(new Object[array.length], depth-1)); 
    } 
    return array; 
} 

// sets a value in the multi dimensional array using the indicies 
public static void setArrayUsingIndecies(Object array, int[] indicies, Object value) { 
    if(indicies.length == 0) 
     return; 

    for(int i=0;i<indicies.length-1;i++) { 
     array = Array.get(array, indicies[i]); 
    } 

    Array.set(array, indicies[indicies.length-1], value); 
} 

// gets a value in the multi dimmensional array using the indicies 
public static Object getArrayUsingIndecies(Object array, int[] indicies) { 

    Object value = array; 
    for(int i=0;i<indicies.length;i++) { 
     value = Array.get(value, indicies[i]); 
    } 

    return value; 
} 

Heres un po 'di codice di esempio

int numberOfDimmensions = 2; 

Object array = constructArray(new Object[numberOfDimmensions], numberOfDimmensions); 

int [] indices = new int [] { 0, 1 }; 
setArrayUsingIndecies(array, indices, "Hello"); 
System.out.println(getArrayUsingIndecies(array, indices)); // Hello 
indices = new int [] { 0, 0 }; 
System.out.println(getArrayUsingIndecies(array, indices)); // null 
0

E' più semplice di quanto pensiamo? Che ne dite di questo approccio:

int [] indices = new int { 2, 7, 3, ... , 4}; // indices of some element 
int X = indices.length; // number of dimensions 
Object array = new Object[X].... // multidimensional array with number of dimensions X 

e poi:

Object myObject = array[indices[1]] // myObject references the 7th element of array 

Bisogna fare in modo però, che l'array indici non contiene un numero maggiore allora la dimensione degli indici - 1. Ad esempio

indices = new int [5,4,3,2,1] // ok 
indices = new int [6,4,3,2,1] // not ok, because you would access the 6th Element in an arry with length 5 
+0

Non si tratta di 'C#'? –

+0

scusa, non capisco il tuo commento? – TimStefanHauschildt