Erick
Erick

Reputation:

Finding the sum of columns in a Two Dimensional Array with rows of different lengths

So i'm having a bit of trouble with my code in returning the sum of the columns in a two dimensional array with rows of different lengths. For example a 2X2 array works perfectly to calculate the sum of the columns. But if I were to have for example a 2X3 array it gives me an out of bounds error. I want it to work for any numbers given by the user for rows and columns not just a fixed number that I said as an example. Can somebody help me resolve this issue? much thanks!

here is my code:

public static void columnSum(int[][]anArray) {
    int totalcol = 0;
    for(int col =0; col < anArray.length; col++){
        totalcol = 0;
        for(int row = 0; row < anArray[col].length; row++) {
            totalcol += anArray[row][col];
        }
    System.out.println("Sum of column " + col + " = " + totalcol);
    }  
}

Upvotes: 0

Views: 1941

Answers (3)

sls
sls

Reputation: 294

The question does not specify the order of the array elements. There are two possiblities:

  1. anArray[i][j] represents the element at row i and column j (row-major)
  2. anArray[i][j] represents the element at column i and row j (column-major)

The easier task to solve is finding column sums in a column-major array, or---completely equivalently---row sums in a row-major array. The proposed solution in the question only needs to replace totalcol += anArray[row][col] with totalcol += anArray[col][row] and would already work for this case.

It is a bit more difficult to compute column sums in a row-major array, or---again equivalently---row sums in a column-major array. The rest of this answer shows how to compute column sums for a row-major array. In this case, anArray.length is the number of rows, and anArray[i].length is the number of columns in row i.


In the more usual case where all your rows have the same number of columns, you could do this:

int numrows = anArray.length;
int numcols = (numrows > 0) ? anArray[0].length : 0; // Guard against 0x0 array

for(int col = 0; col < numcols; col++) {
    int totalcol = 0;
    for(int row = 0; row < numrows; row++) {
        totalcol += anArray[row][col];
    }
    System.out.println("Sum of column " + col + " = " + totalcol);
}

If your rows may each have a different number of columns (as suggested by the question title), you need to:

  1. Determine when there are no more columns to sum over.
  2. When computing the sum of column col, make sure to skip rows that are too short

One way would be:

int numrows = anArray.length;

for(int col = 0; /* not known a priori*/; col++) {
    int totalcol = 0;
    boolean emptySum = true; // At first, assume no rows are long enough
    for(int row = 0; row < numrows; row++) {
        if(anArray[row].length <= col ) continue; // Skip short row
        emptySum = false; // Mark assumption as wrong
        totalcol += anArray[row][col];
    }

    // Exit the loop if we did not sum anything, i.e. no row had a column with index col
    if(emptySum) break;

    System.out.println("Sum of column " + col + " = " + totalcol);
}

Instead of using the awkward emptySum flag to quit the loop, you could determine the maximal column length in a preliminary pass:

int numrows    = anArray.length;
int maxnumcols = (numrows > 0) ? anArray[0].length : 0; // Guard against 0x0 array

for(int row = 1; row < numrows; row++) {
    maxnumcols = Math.max(maxnumcols, anArray[row].length);
}

for(int col = 0; col < maxnumcols; col++) {
    int totalcol = 0;
    for(int row = 0; row < numrows; row++) {
        if(anArray[row].length <= col) continue; // Skip short row
        totalcol += anArray[row][col];
    }
    System.out.println("Sum of column " + col + " = " + totalcol);
}

Finally, if you are allowed to store the sums (instead of immediately outputting them), this would be an even cleaner solution (note the row-major order of iteration, which fits nicely to the row-major order of the array itself):

int numrows    = anArray.length;
int maxnumcols = (numrows > 0) ? anArray[0].length : 0; // Guard against 0x0 array

for(int row = 1; row < numrows; row++) {
    maxnumcols = Math.max(maxnumcols, anArray[row].length);
}

int[] colsums = new int[maxnumcols]; // In Java, all elements are initialized to zero

for(int row = 0; row < numrows; row++) {
    for(int col = 0; col < anArray[row].length; col++) {
        colsums[col] += anArray[row][col];
    }
}

for(int col = 0; col < colsums.length; col++) {
    System.out.println("Sum of column " + col + " = " + colsums[col]);
}

Upvotes: 0

Ross Patterson
Ross Patterson

Reputation: 9569

Your indices are flipped. Your for loops are written for column-major ordering, but your totalizer is written for row-major order. You need to reverse one or the other.

Upvotes: 1

Blip
Blip

Reputation: 3171

You have a problem in the for loop

    for(int row = 0; row < anArray[col].length; row++) {
        totalcol += anArray[row][col];
    }

If the array is 2X3 then in this for loop when you are using the col = 0 Then anArray[col].length returns value 3. So your row variable can have values 0 - 2 in the for loop. So when the value of row is 2 and the value of column is 0 (as stated earlier), anArray[row][col] will throw an ArrayOutOfBoundException as anArray[2][0] does not exists.

So try out this instead:

    for(int row = 0; row < anArray.length; row++) {
        totalcol += anArray[row][col];
    }

I think this will work.

Upvotes: 0

Related Questions