23

I have two arrays for a chess variant I am coding in java...I have a console version so far which represents the board as a 1D array (size is 32) but I am working on making a GUI for it and I want it to appear as a 4x8 grid, so I have a 2-dimensional array of JPanels...

Question is, is there any formula that can convert the array[i][j] index into array[i] given the fact its a 4x8 array?

Becky
  • 893
  • 3
  • 9
  • 14

5 Answers5

41

Think of it this way:

You have one array that happens to be a 1 dimensional array, which really, is just a long concatenation of items of a two dimensional array.

So, say you have a two dimensional array of size 5 x 3 (5 rows, 3 columns). And we want to make a one dimensional array. You need to decide whether you want to concatenate by rows, or by columns, for this example we'll say the concatenation is by rows. Therefore, each row is 3 columns long, so you need to think of your one-dimensional array as being defined in "steps" of 3. So, the lengthy of your one dimensional array will be 5 x 3 = 15, and now you need to find the access points.

So, say you are accessing the 2nd row and the 2nd column of your two dimensional array, then that would wind up being 3 steps (first row) + the number of steps in the second row, or 3 + 2 = 5. Since we are zero-based indexing that is -1, so that would be at index 4.

Now for the specific formulation:

int oneDindex = (row * length_of_row) + column; // Indexes

So, as an example of the above you would wind up having

oneDindex = (1 * 3) + 1

And that should be it

Michael
  • 1,626
  • 11
  • 23
  • 1
    Great! Thanks a lot for explaining how to get to the formula! – teo Aug 25 '12 at 19:41
  • @Michael it was a great explanation and even +1 u but can you please elaborate this "So, say you are accessing the 2nd row and the 2nd column of your two dimensional array, then that would wind up being 3 steps (first row) + the number of steps in the second row, or 3 + 2 = 5. Since we are zero-based indexing that is -1, so that would be at index 4." better. explain it better. – Kick Buttowski Nov 30 '14 at 05:37
32

Given 4 columns by 8 rows then:

i = row * 4 + col

EDIT: My bad, nobody caught me on this mistake apparently. But it should actually be row * 4 + col.

row * 8 + col would leave unnecessary gaps in the possible indexes.

cdmckay
  • 31,832
  • 25
  • 83
  • 114
Steve Wortham
  • 21,740
  • 5
  • 68
  • 90
  • I can't believe I didn't get that lol...I had (i*4)+(i*8) no wonder it was out of bounds, thankyouu! – Becky Nov 13 '09 at 18:22
  • You're very welcome. I had to do the exact same thing recently with a Tic Tac Toe game that learns. Storing past moves as a single index was a step towards improving efficiency. – Steve Wortham Nov 13 '09 at 18:43
  • 4
    I always keep coming back to this answer, for some reason I just can't find a way to memorize this equation `index = x + y * num_cols;` would be nice to add how we deduce it! – vexe Nov 20 '15 at 18:02
  • Simple and elegant. – Saqib Ahmed Oct 07 '19 at 11:00
  • @vexe I know it's been 7 years and you probably don't need it anymore, but the way you deduce that is that each time you complete a row in iteration, the `y` index increases by 1 and `x` resets to 0. So in order to not override previous data, you essentially have to "skip" the size of a row in the 1d array. hence the `y * num_cols`. – PNarimani May 07 '22 at 10:07
11

Every row in your 2D array is placed end to end in your 1D array. i gives which row you are in, and j gives the column (how far into that row). so if you are in the ith row, you need to place i complete rows end to end, then append j more onto that to get your single array index.

So it will be something like
singleDimIndex = array[0].length * i + j

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
3

i*8+j (assuming 8 is the horizontal width)

mr grumpy
  • 1,513
  • 1
  • 10
  • 17
3

You could use this ArrayConvertor class to convert 2D arrays in 1D arrays and back.

Beware: Converting a 2D array to a normal one does only work with a matrix.

public class ArrayConvertor {
    static public int[] d2Tod1(int[][] array){

        int[] newArray = new int[array.length*array[0].length];

        for (int i = 0; i < array.length; ++i) 
        for (int j = 0; j < array[i].length; ++j) {
            newArray[i*array[0].length+j] = array[i][j];
        }

        return newArray;
    }

    static public int[][] d1Tod2(int[] array, int width){

        int[][] newArray = new int[array.length/width][width];

        for (int i = 0; i < array.length; ++i) {
           newArray[i/width][i%width] = array[i];
        }

        return newArray;
    }
}

And Some testing code:

public class JavaMain{
    public static void main(String[] args) {
        int[][] arr2D_1 = new int[4][8];

        byte counter=0;
        for (int i = 0; i < 4; i++) 
        for (int j = 0; j < 8; j++) {
            arr2D_1[i][j] = counter++;
        }

        int[]arr1D = ArrayConvertor.d2Tod1(arr2D_1);
        int[][] arr2D_2 = ArrayConvertor.d1Tod2(arr1D, 8);

        boolean equal = true;
        for (int i = 0; i < arr2D_1.length; i++) 
        for (int j = 0; j < arr2D_1[0].length; j++){ 
            if(arr2D_1[i][j]!=arr2D_2[i][j]) equal=false;
        }

        System.out.println("Equal: "+equal);
    }
}

Output: Equal: true

call-me
  • 686
  • 9
  • 18