1

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.

v1shnu
  • 2,211
  • 8
  • 39
  • 68
  • 1
    Perhaps you could first (a) read the documentation: https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#copyOfRange(byte[],%20int,%20int), (b) Give it a try. If this does not work for you, then post the code you have tried with your specific problem. – EJK Dec 07 '14 at 14:52
  • Yes, I saw the documentation. But I could find that copyofrange can obtain data from a single dimensional array. I want to know how it can done for a 2d array. I can use the centre 2x2 in the 4x4 matrix and get the elements surrounding each element of the 2x2 to get the required 3x3 array using for loops . Just wanted to know if there is an easy way. – v1shnu Dec 07 '14 at 15:01
  • If you added some more information about what you are going to do with these sub-arrays, one might give further hints. For example, you might consider an `interface Array2D { ... }` that has a method `Array2D getSubArray(...)` that only returns a *view* on the sub-array. Many solutions are possible here, and some might be more elegant than copying, depending on the application case. – Marco13 Dec 07 '14 at 16:47

1 Answers1

0

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.

Adriaan Koster
  • 15,870
  • 5
  • 45
  • 60