简体   繁体   中英

Counting Connections in a m*n matrix

I am trying to find the expected output to the below program..But I am getting the error

  Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
  at programbasics.CountingConnections.count(CountingConnections.java:7)
  at programbasics.CountingConnections.main(CountingConnections.java:26)

My question is about a matrix m*n . The elements in matrix are populated with values 1 and 0 .

1 indicates in establishing connection and 0 indicates Not establishing connection.

we need to connect the available adjacent positions vertically, horizontally and diagonally and count the number of distinct connections established

My piece of code is

  package programbasics; 
  class CountingConnections
  {
    static int count(int a[][], int i, int j) {
    int rows = a.length;
    int cols = a[0].length;
    if(a[i][j] == 0)  return 0;
    if (i == rows - 1 && j == cols - 1)
        return a[i][j];
    else if (i == rows - 1)
        return a[i][j + 1];
    else if (j == cols - 1)
        return a[i + 1][j];
    else if (a[i][j] == 1)
        return count(a, i + 1, j) + count(a, i, j + 1);
    else
        return 0;
   }
  public static void main(String[]args)
   {
   int a[][] = {{1,0,0,1},
             {0,1,1,1},
             {1,0,0,1}};
      int i = 3;
      int j = 4;
      System.out.println(count(a, i, j));;
    }
 }

The expected output is 8 . Like the positions are connected as follows
1)(0,0) -> (1,1)
2)(2,0) -> (1,1)
.
.
.
.
8) (0,3) -> (1,3)

It fails to get the expected output 8 .


         public static int count(int[][] a) {
         int[][] paths = new int[a.length][a[0].length];
         if ((paths[0][0] = a[0][0]) == 0) {
         return 0;
          }
         for (int c = 1; c < a[0].length; c++) {
           paths[0][c] = a[0][c] * paths[0][c - 1];
           }
            for (int r = 1; r < a.length; r++) 
           { 
         paths[r][0] = a[r][0] * paths[r - 1][0];
           for (int c = 1; c < a[r].length; c++) 
             {
        paths[r][c] = a[r][c] * (paths[r - 1][c] + paths[r][c - 1]);
          }
        }
           return paths[a.length - 1][a[0].length - 1];
        }
public static int count(int[][] a, int m, int n) {

    int count = 0;

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {

            if (a[i][j] == 1) {
                if (i - 1 >= 0 && j - 1 >= 0 && a[i - 1][j - 1] == 1) {
                    count = count + 1;

                }
                if (i - 1 >= 0 && a[i - 1][j] == 1) {
                    count = count + 1;
                }
                if (i - 1 >= 0 && j + 1 < n && a[i - 1][j + 1] == 1) {
                    count = count + 1;
                }
                if (j + 1 < n && a[i][j + 1] == 1) {
                    count = count + 1;
                }
            }
        }
    }


    return count;
}

You call if(a[i][j] == 0) in your code where you pass 3 as i and 4 as j . However Array 's are zero indexed, so when you try to call a[3][4] you are trying to call

     0    1    2    3    4

0   {1,   0,   0,   1}

1   {0,   1,   1,   1}

2   {1,   0,   0,   1}

3                         X

4

The index where the X is. Clearly this is not a valid index in your Array .

Also your method at different points calls a[i + 1][j] and a[i][j + 1] which means that you will have to take this in account when making sure the code stays in bounds.

As to your actual method your logic seems a bit off. if(a[i][j] == 0) return 0; will return 0 and stop the recursion and return 0 without checking to see if there are any more connections. Your logic should be something more like this:

  1. Start at 0,1.
  2. If the index is a 1 Look one index to the right, one down and to the right (The diagonal) down one, and down one and to the left (The second diagonal).
    If any of the numbers at those index's are 1 's then up the counter.
  3. Continue to iterate through the matrix, but keep in mind that you are checking one row down and over, so you will only loop until less than length -1 for for both the row and column. Also make sure that you are starting at index a[i][1] as you will be needing to check a[a+1][j-1] and if j == 0 you will be trying to call a[a+1][-1] which will cause another index out of bounds
private int countConnections(int[][] a, int rows, int columns) {
    //cartesian plane coordinates around a point
    final int[] x = {1, 1, 1, -1, -1, -1, 0, 0};
    final int[] y = {1, -1, 0, 1, -1, 0, 1, -1};
    int count = 0;
    boolean[][] visited = new boolean[rows][columns];
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
            for (int k = 0; k < 8; k++) {
                int l = i + x[k];
                int m = j + y[k];
                //check for connections only if the given cell has value 1
                if (a[i][j] == 1 && canVisit(l, m, rows, columns, visited) && a[l][m] == 1) {
                    count++;
                }

            }
            visited[i][j] = true;
        }
    }
    return count;
}

private boolean canVisit(int i, int j, int rows, int columns, boolean [][] visited) {
    return i < rows && j < columns && i >= 0 && j >= 0 && !visited[i][j];
}

Check all the 8 cells around a cell whose cell value is 1 and when traversed mark it as visited.

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