javaarraysmatrixdimensional

How to obtain a part of a 2d array?


Suppose if I have a 4x4 array matrix like

aaaa
abba
abba
aaaa

Can I obtain a 3x3 matrix from the above matrix and store it in another 2d array. The 3x3 matrix should contain the elements

aaa
abb
abb 

likewise

aaa
bba
bba

and two more matrices.

Can this be done using Arrays.copyOfRange ??

EDIT: I also want the other 2 3x3 matrices ie.

abb
abb
aaa

and

bba
bba
aaa

Like if I pass the elements in the 2x2 matrix which in the 4x4 ie. b's , it should give me a 3x3 matrix surrounding the element.

I can make this happen by using a for loop which takes the i and j values from subtracting 1 from the index of the element ( here 'b') which I'm passing , which results in a 3x3 matrix surrounding the value b ( given above ) . But just want to know if there is an easier way.


Solution

  • I would use System.lang.arrayCopy:

    import java.util.Arrays;
    
    public class ArrayRange {
    
        public static void main(String[] args) {
    
            char[][] original = createMatrix(4);
    
            // copy 3x3 array starting at 1,0
            char[][] subArray = copySubrange(original, 1, 0, 3, 3);
    
            printArray(original);
            printArray(subArray);
        }
    
        private static char[][] copySubrange(char[][] source, int x, int y, int width, int height) {
            if (source == null) {
                return null;
            }
            if (source.length == 0) {
                return new char[0][0];
            }
            if (height < 0) {
                throw new IllegalArgumentException("height must be positive");
            }
            if (width < 0) {
                throw new IllegalArgumentException("width must be positive");
            }
            if ((y + height) > source.length) {
                throw new IllegalArgumentException("subrange too high");
            }
            char[][] dest = new char[height][width];
            for (int destY = 0; destY < height; destY++) {
                char[] srcRow = source[(y + destY)];
                if ((x + width) > srcRow.length) {
                    throw new IllegalArgumentException("subrange too wide");
                }
                System.arraycopy(srcRow, x, dest[destY], 0, width);
            }
            return dest;
        }
    
        // Set up a matrix as an array of rows.
        // The y-coordinate is the position of a row in the array.
        // The x-coordinate is the position of an element in a row.
        private static char[][] createMatrix(int size) {
            char[][] original = new char[size][size];
            for (int y = 0; y < original.length; y++) {
                for (int x = 0; x < original[0].length; x++) {
                    original[y][x] = (char) (Math.random() * 10 + 48);
                }
            }
            return original;
        }
    
        private static void printArray(char[][] array) {
            for (int y = 0; y < array.length; y++) {
                System.out.println(Arrays.toString(array[y]));
            }
            System.out.println();
        }
    }
    

    Example output:

    [0, 7, 4, 3]
    [9, 2, 7, 2]
    [9, 2, 4, 0]
    [9, 1, 5, 9]
    
    [7, 4, 3]
    [2, 7, 2]
    [2, 4, 0]
    

    EDIT: improved code with range checks.