Reputation:
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
Reputation: 294
The question does not specify the order of the array elements. There are two possiblities:
anArray[i][j]
represents the element at row i
and column j
(row-major)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:
col
, make sure to skip rows that are too shortOne 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
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
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