简体   繁体   中英

How can I visualize what the loop is doing when traversing through a 2D array?

Consider this code:

import java.util.Arrays;

public class Test {
    static int[] getDiagonal(int[][] a) {
        int diagonal[] = new int[a.length];
        for (int i = 0; i < a.length; i++) {
            diagonal[i] = a[i][i];
        }
        System.out.println(Arrays.toString(diagonal));
        return diagonal;
    }

    public static void main(String[] args) {
        int[][] rnd_array = {{1, 2, 4}, {6, 7, 3}, {11, 4, 5}};
        getDiagonal(rnd_array);
    }
}

The goal of this code is to get the diagonal of a 2D matrix that has the same number of rows and columns. The code works just fine but I don't understand how. The part that isn't clear to me is how are we able to traverse both rows and columns of a 2D array with just one loop. I've tried doing it with 2 for loops but I am not getting the wanted results. How could I visualize the traversal of a 2D array, and how is it possible that we are able to traverse it with only 1 loop?

Try not not imagine as "array traversing", but follow what does the for loop actually do: You declare a variable i and increment it after every iteration and using it to access the arrays. For the outer array, you say "give me first, second, third, ... element" ( a[i] ). That's equivalent to for each in lists - you go over all elements of the outer array. But on the result (inner array), you access i th element again ( a[i][i] ) - which means that you're not iterating over every element of the inner array, but just one - first element of the first array, second element of the second array etc.

Java doesn't have 2D arrays. The only thing it does have is some very light syntax sugar support for making 1D arrays whose components are themselves 1D arrays. This can look like a 2D array for all intents and purposes, but it also highlights the trick for how to 'visualize' working with what you termed '2D arrays'.

> int[][] a

This is no different from any other array declaration, and java does not have 2D arrays. Therefore, you should read that as X[] a , where X is any type. After all, you can make int[] , but you can also make String[] or List<?>[] - you can make an array out of any type. In this case, you're making an array whose components are of the int[] type: An array of int arrays.

Crucial thing to understand: Those component arrays do NOT need to be the same size! This is perfectly legit java code:

int[][] a = new int[][2];
// just like any other array of non-primitives,
// each component slot starts out as null!

System.out.println(a[0]);
> null
// see?

a[0] = new int[5];
System.out.println(Arrays.asList(a[0]));
> [0, 0, 0, 0, 0]
a[0][2] = 9;
System.out.println(Arrays.asList(a[0]));
> [0, 0, 9, 0, 0]

a[0] is an expression that resolves to whatever is in the first 'slot' of the array referenced by your a variable. The [2] that follows immediately after is then applying the 'and give me the 3rd slot' to whatever you found at a[0] . So, a[0][2] is: The third slot in the array you find by looking in the first slot of the thing a is pointing at.

a[1] = new int[3]

Now you don't have a 2D array in any sense of the word. Because the first 'row' of your '2D' array has 5 elements and the second row has only 3.

a = new int[10][10];

This is that light syntax sugar I told you about earlier: This is just syntax sugar for:

a = new int[][10];
for (int i = 0; i < a.length; i++) {
    a[i] = new int[10];
}

The part that isn't clear to me is how are we able to traverse both rows and columns of a 2d array with just one loop

That's good news! Because your code does not traverse both rows and columns of a 2D array at all. What it is doing is hitting the diagonal and only the diagonal.

First, realize that this code fundamentally assumes you don't have a 'broken' array like we made before - that it is an array of arrays of size X, and each array component is also of size X. Otherwise it's going to throw exceptions.

With that established, let's visualize that array-of-arrays:

0 1 2
3 4 5
6 7 8

Then this code is just hitting a[0][0] , a[1][1] , and a[2][2] : Just 0, 4, and 8. That's only 3 elements. Makes sense; the diagonal of a 15x15 array consists of 15 numbers - that math almost works out. So, there is no need to loop over 9 elements in this example 3x3 array to 'find' the numbers on the diagonal.

If you really wanted to run this code but with a full loop (which is entirely inefficient), but just for sake of learning:

for (int x = 0; i < a.length; x++) {
    for (int y = 0; j < a[x].length; y++) {
        if (x == y) {
           // it is on the diagonal!
           diagonal[x] = a[x][y];
        } else {
           // not on the diagonal, so...
           // do not do anything at all.
        }
    }
}

That works fine too. It's just a slower, as it needs to check out n^2 elements instead of just looking at a[i][i] which only needs to check n elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM