Adding each column inside a Jagged array not working - java

I have been recently working with 2D and Jagged Arrays and am trying to add each element in a row and each element inside a column. I got the code to print out the sum of each row, but am having difficulty with adding each column in the array.
Note: I tried doing sum += numbers[c][r]; but it is not working
import java.util.Arrays;
import java.io.*;
public class Homework{
public static void main(String[] args) {
int[][] numbers = { {3, 2, 5,},
{1, 4, 4, 8, 13},
{9, 1, 0, 2},
{0, 2, 6, 3, -1, -8} };
//Adding each row in the array
int sum = 0;
for(int r = 0; r < numbers.length; r++) {
sum = 0;
for(int c = 0; c < numbers[r].length; c++) {
sum += numbers[r][c];
}
System.out.println("Sum of row: " + sum);
}
//Adding each column in the row
int sum2 = 0;
for(int r = 0; r < numbers.length; r++) {
sum2 = 0;
for(int c = 0; c < numbers[r].length; c++) {
sum2 += numbers[c][r];
}
System.out.println("Sum of column: " + sum2);
}
}
}

Okay so you were sort of on the right track. Let me explain a way of thinking before I get into the code.
You have a non-square 2d Array and you want the total of each row and column. Row is simple, you've accomplished that already. Column is a little more difficult because since its non-square, you will run into ArrayOutOfBoundsExceptions because it tries to access a art of the array that doesn't exist.
To combat this, you need to know the max number of columns there are and then iterate through the array. BUT, you also need to be careful about that ArrayOutOfBoundsException, making sure to account for when the current column iteration is greater than the row length.
I added an int max to your row sum section, this way I don't have to iterate over the same info more than once.
After that, I replace c < numbers[r].length with 'max', since we need to iterate over X columns.
Then I iterate over the rows, since they are uniform and easily found by numbers.length.
So, a simple change to your code yields the results you need. See below.
int[][] numbers = {
{3, 2, 5},
{1, 4, 4, 8, 13},
{9, 1, 0, 2},
{0, 2, 6, 3, -1, -8}
};
int max = 0;
//Adding each row in the array
int sum;
for(int r = 0; r < numbers.length; r++) {
sum = 0;
for(int c = 0; c < numbers[r].length; c++) {
sum += numbers[r][c];
if(numbers[r].length > max){
max = numbers[r].length;
}
}
System.out.println("Sum of row: " + sum);
}
System.out.println("Max " + max);
//Adding each column in the row
int sum2;
for(int c = 0; c < max; c++) {
sum2 = 0;
for(int y = 0; y < numbers.length; y++){
if(numbers[y].length > c){
sum2 += numbers[y][c];
System.out.println(numbers[y][c]);
}
}
System.out.println("Sum of column: " + sum2);
}
}

Related

How to get the highest row and column of a 2D array in Java

I'm stuck on a problem where I am supposed to make a method that returns the row with the highest average number in a 2D array
The method that I attached here only gets the averages of each row.
I believe that I need to keep track the row with the highest average but I just don't know how
Any suggestions?
int[][] array = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
public static double getRowAverage(int grid[][]) {
int i, j;
double sum = 0, average = 0;
for (i = 0; i < grid.length; i++) {
for (j = 0; j < grid[i].length; j++) {
sum = sum + grid[i][j];
}
average=sum/grid[i].length;
System.out.println("Average of row " + (i+1) + " = " + average);
sum=0;
double a = i+1;
}
return average;
}
You can compare and check if the row average is higher than the current highest
double rowAverage = sum / grid[i].length;
average = rowAverage > average ? rowAverage : average;
or even better, use Math.max
average = Math.max(average, sum / grid[i].length);
Some notes regarding the code in your question.
As well as sum, you also need to zero average for each new row.
No need to declare loop variables i and j outside of the loop.
Java has "short-circuit" statements like +=.
I understand that the purpose of this line:
double a = i+1;
is to store the index of the row (in the grid) that contains the highest average. That variable should be int (and not double) since a row index can only be an int. The variable should also be declared outside of the outer for loop since you can only know its final value after you have processed all the rows in grid. In the code below, I renamed a to maxRow.
You need another variable to store the maximum.
Note that I assume that all the integers in grid are positive – as per the example in your question.
public class Averages {
public static void main(String[] args) {
int[][] grid = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
double maxAvg = 0.0;
int maxRow = -1;
for (int i = 0; i < grid.length; i++) {
double sum = 0, average = 0;
for (int j = 0; j < grid[i].length; j++) {
sum += grid[i][j];
}
average = sum / grid[i].length;
if (average > maxAvg) {
maxAvg = average;
maxRow = i;
}
System.out.println("Average of row " + (i+1) + " = " + average);
}
System.out.println("Row with highest average: " + (maxRow + 1));
}
}
When I run the above code, I get the following output:
Average of row 1 = 2.0
Average of row 2 = 5.0
Average of row 3 = 8.0
Row with highest average: 3

Filling a jagged 2d array first by columns

I want to write a function that takes an 2d array and fills it with 1...n but counting the columns first instead of the rows:
input = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
the output should be: {{1, 5, 7, 8}, {2}, {3}, {4, 6}};
if i were to loop through rows and then colums i get:
private static void fill1(int[][] input) {
int count = 1;
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input[i].length; j++) {
input[i][j] = count;
count++;
}
}
}
How do I loop through colums first?
You can do this by first transposing your input, executing your fill1 code and then transposing the output again.
See this question for how to transpose a 2 dimensional array in Java: java multi-dimensional array transposing
If you were dealing with a regular 2d matrix, where all the rows had the same number of columns, the code would be a simple modification of the code for filling the matrix row-by-row:
private static void fill1(int[][] input) {
int count = 1;
for (int j = 0; j < input[0].length; j++) {
for (int i = 0; i < input.length; i++) {
input[i][j]= count;
count++;
}
}
}
The process is basically the same for a ragged 2d array, but with a couple added twists:
You need to do some extra work to figure out how many columns there could be (i.e., the maximum row length)
You need to be prepared for the case when there's no cell at a given row/column position.
The following modification of the previous code addresses these issues:
private static void fill1(int[][] input) {
int maxCols = input[0].length;
for (int i = 1; i < input.length; ++i) {
if (input[i].length > maxCols) {
maxCols = input[i].length;
}
}
int count = 1;
for (int j = 0; j < maxCols; j++) {
for (int i = 0; i < input.length; i++) {
if (j < input[i].length) {
input[i][j]= count;
count++;
}
}
}
}
To iterate first over the columns of a jagged 2d array to fill it, you have to know the maximum number of columns beforehand, but if you don't know that, you can iterate to the Integer.MAX_VALUE and check at each step if the columns are still present or not:
int[][] arr = {{0, 0, 0, 0}, {0}, {0}, {0, 0}};
int count = 1;
for (int col = 0; col < Integer.MAX_VALUE; col++) {
boolean max = true;
for (int row = 0; row < arr.length; row++) {
if (col < arr[row].length) {
arr[row][col] = count;
count++;
max = false;
}
}
if (max) break;
}
for (int[] row : arr) {
System.out.println(Arrays.toString(row));
}
Output:
[1, 5, 7, 8]
[2]
[3]
[4, 6]
See also: How do you rotate an array 90 degrees without using a storage array?
To populate a 2d array first by columns, you can use two nested streams. In case of a jagged 2d array, when you don't know beforehand the number of the columns in each row, in an outer stream you can traverse while the columns are still present.
/**
* #param arr array that should be populated.
* #return maximum row length, i.e. columns count.
*/
private static long populate(int[][] arr) {
AtomicInteger counter = new AtomicInteger(1);
return IntStream
// traverse through the array columns
.iterate(0, i -> i + 1)
// process the array rows where
// this column is present
.mapToLong(i -> Arrays.stream(arr)
// filter those rows where
// this column is present
.filter(row -> row.length > i)
// assign a value to the element and increase the counter
.peek(row -> row[i] = counter.getAndIncrement())
// count of rows where this column is present
.count())
// while the columns are still present
.takeWhile(i -> i > 0)
// max columns count
.count();
}
public static void main(String[] args) {
int[][] arr = {{0, 0, 0, 0, 0, 0}, {0, 0}, {0}, {0, 0, 0}};
System.out.println("Max columns count: " + populate(arr));
System.out.println(Arrays.deepToString(arr));
}
Output:
Max columns count: 6
[[1, 5, 8, 10, 11, 12], [2, 6], [3], [4, 7, 9]]
See also: How to create a new List from merging 3 ArrayLists in round robin style?

Finding a row sums of a 2D array

I want to find the sum of the first row and second row of a 2D array of integers. This is my code and is there any way I can make this code shorter?
//creating 2D array for integers
int[][] num = {{1, 2, 3}, {4, 5, 6}};
int sum1 = 0;
int sum2 = 0;
//sum for first row
for (int a = 0; a == 0; a++) {
for (int b = 0; b <= 2; b++) {
sum1 += num[a][b];
}
System.out.println(sum1);
}
//sum for second row
for (int a = 1; a == 1; a++) {
for (int b = 0; b <= 2; b++) {
sum2 += num[a][b];
}
System.out.println(sum2);
}
Output is:
6
15
You can use streams to get an array of row sums of a 2d array as follows:
int[][] num = {{1, 2, 3}, {4, 5, 6}};
int[] sum = Arrays.stream(num)
.map(Arrays::stream)
.mapToInt(IntStream::sum)
.toArray();
System.out.println(Arrays.toString(sum)); // [6, 15]
Yes,
int[][] num = {{1, 2, 3}, {4, 5, 6}};
int sum1 = 0;
int sum2 = 0;
//sum for first row and second row
for (int a = 0; a <= 1; a++) {
for (int b = 0; b <= 2; b++) {
if (a == 0)
sum1 += num[a][b];
else
sum2 += num[a][b];
}
}
System.out.println(sum1); // 6
System.out.println(sum2); // 15
This may help you:
int[][] num = {{1, 2, 3}, {4, 5, 6}};
for (int a = 0; a <= 1; a++) {
int sum1 = 0;
for (int b = 0; b <= 2; b++) {
sum1 += num[a][b];
}
System.out.println(sum1);
}
You could use the Streams API:
import java.util.Arrays;
import java.util.stream.IntStream;
int[][] num = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};
// sum of all elements in the 2D array
int sum = Arrays.stream(num).mapToInt(a -> IntStream.of(a).sum()).sum();
This sums all elements of the 2D array. This way your code sums the entire grid even if you add more rows or add more elements to each row.
If you need the sum of each row separately, consider this:
import java.util.stream.IntStream;
int[][] num = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};
// sum of the first row
int sum1 = IntStream.of(num[0]).sum();
// sum of the second row
int sum2 = IntStream.of(num[1]).sum();
You can think about 2D array as an array of arrays.
You can simply iterate over the "big array" (lets call the index i) and then take the array on the i place and iterate over him (lets call the index j).
Now you can simply sum up the value on place [i][j] with the current value of a 0 initialized variable (lets call it sum).
in java:
int sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; i++)
sum += array[i][j];
}
// Output: 21
Or if you want to print only the sub arrays sum you can print the sum and initialize it when the second loop finished:
int sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; i++)
sum += array[i][j];
System.out.println(sum);
sum = 0;
}
// Output:
// 6
// 15
Because we're going to go through all the elements, in terms of time, O(n) is the optimal time complexity.
int sum1 = 0;
int sum2 = 0;
//sum for first row
for (int b = 0; b <= 2; b++) {
sum1 += num[0][b];
}
System.out.println(sum1);
//sum for second row
for (int b = 0; b <= 2; b++) {
sum2 += num[1][b];
}
System.out.println(sum2);
The outer loop in both instances is redundant, since it basically only deals as a variable declaration & initialization. This loop is not needed since it is only run once anyways.
You should also not use fixed sizes for your loops, as this will break your code once you alter the size of your array.
Also, I would suggest you use an array to store the sum for each row.
Example with all the suggestions:
public static void main(String[] args) {
int[][] nums = {{1, 2, 3}, {4, 5, 6}};
// hold the sum of each row in an array
int[] sums = new int[nums.length];
// loops shouldn't use fixed sizes, they
// should run according to the arrays size
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[i].length; j++) {
// for each row, calculate the sum
// and store it in the sum array
sums[i] += nums[i][j];
}
}
System.out.println(Arrays.toString(sums));
}
Output:
[6, 15]

How to calculate the sum of each column in a 2D array?

I'm writing a program so that it computes and prints the sum of each column of the array. The given data looks like this:
int[][] data = {{3, 2, 5},
{1, 4, 4, 8, 13},
{9, 1, 0, 2},
{0, 2, 6, 3, -1, -8}};
Ideally, it should output the results 13, 9, 15, 13, 12, -8. But since some of the rows have different lengths, when I run my program, it outputs 13, 9, 15 and gives me an ArrayIndexOutOfBoundsException. And I really don't know how to fix it.
Here is my code:
public class ColumnSums
{
public static void main(String[] args) {
//The given data
int[][] data = {{3, 2, 5},
{1, 4, 4, 8, 13},
{9, 1, 0, 2},
{0, 2, 6, 3, -1, -8}};
//Determine the number of data in the longest row
int LongestRow = 0;
for ( int row=0; row < data.length; row++){
if ( data[row].length > LongestRow ){
LongestRow = data[row].length;
}
}
System.out.println("The longest row in the array contains " + LongestRow + " values"); //Testing
//Save each row's length into a new array (columnTotal)
int[] columnTotal = new int[4];
//Scan through the original data again
//Record each row's length into a new array (columnTotal)
System.out.println("The lengths of each row are: ");
for ( int i = 0; i < data.length; i++){
columnTotal[i] = data[i].length;
System.out.println(columnTotal[i]); //Testing
}
// Create an array to store all the sums of column
int ColumnSums[] = new int[LongestRow];
System.out.println("The sums of each column are: ");
for ( int i = 0; i < LongestRow; i++ ){
int sum = 0;
for (int j = 0; j < data.length; j++) {
sum = sum + data[j][i];
}
ColumnSums[i] = sum;
System.out.println("Column " + i + ": " + ColumnSums[i]); //Testing
}
}
}
Thanks for your time!!!
You basically just need to loop through the columns until the counter is out of bounds for every row. No need to loop through ahead of time to find the longest row.
public static ArrayList<Integer> getCollumnSum() {
int[][] data = {{3, 2, 5},
{1, 4, 4, 8, 13},
{9, 1, 0, 2},
{0, 2, 6, 3, -1, -8}};
int col = 0;
ArrayList<Integer> totals = new ArrayList<Integer>();
while (true) {
int total = 0;
boolean dataInCol = false;
for (int i = 0; i < data.length; i++) {
if (col < data[i].length) {
total += data[i][col];
dataInCol = true;
}
}
col += 1;
if (dataInCol) {
totals.add(total);
} else {
break;
}
}
return totals;
}
Output:
[13, 9, 15, 13, 12, -8]
To read a 2D array your loops should be
for(int i = 0; i < array.length; ++i){
for(int j = 0; j < array[i].length; ++j){
System.out.println(array[i][j]);
}
}
See the use of for(int j = 0; j < array[i].length; ++j) to use the current row length.
With this, you will prevent this ArrayIndexOutOfBoundsException
I am open to question if you need. Just post a comment !
I have altered your code to fit your needs
int[][] data = {{3, 2, 5},
{1, 4, 4, 8, 13},
{9, 1, 0, 2},
{0, 2, 6, 3, -1, -8}};
int longestRow = 0;
for ( int row=0; row < data.length; row++){
if ( data[row].length > longestRow ){
longestRow = data[row].length;
}
}
System.out.println("The longest row in the array contains " + longestRow + " values");
Here, no need for columnTotal as I can't notice any use of it. It maybe your program need. Anyway, you can print the length of each row directly as below.
System.out.println("The lengths of each row are: ");
for ( int i = 0; i < data.length; i++){
System.out.println("Row " + i + " is " + data[i].length);
}
You can't get the sum of each column at each inner loop, because the sum of each column will be obtained after the both loops finish. Therefore, the variable sum is useless. So, it would be like below
int columnSums[] = new int[longestRow];
for ( int i = 0; i < data.length; i++ ){
for (int j = 0; j < data[i].length; j++){
columnSums[j] +=data[i][j];
}
}
Finally, you can print the sum of each column as below
System.out.println("The sums of each column are: ");
for (int i = 0; i < columnSums.length; i++) {
System.out.println("Column " + i + ": " + columnSums[i]);
}
After running the code, the output would be:
The longest row in the array contains 6 values
The lengths of each row are:
Row 0 is 3
Row 1 is 5
Row 2 is 4
Row 3 is 6
The sums of each column are:
Column 0: 13
Column 1: 9
Column 2: 15
Column 3: 13
Column 4: 12
Column 5: -8

Java Multidimensional array and integer occurrences

I have this integer array called numList which has
[4, 4, 3, 3, 3, 2, 1, 1, 1, 1, -1, -12, -12, -12, -12]
I would like to create a multidimensional array which can store
Which left side represents the number and the right side determines the number of occurrences.
The attempt i tried... i got nowhere.
// Declaring the new multi-dimensional array.
int [] [] newArray = new int [6] [2];
// Counter 3.
int counter3 = 0;
// Get first occurrence.
while (numList[counter3] < numList.length){
for (int counter3:numList){
newArray[] ([counter3]++);
}
Assuming your numbers are in order as they are in your example numList, then you could do this:
int[] numList = { 4, 4, 3, 3, 3, 2, 1, 1, 1, 1, -1, -12, -12, -12, -12 };
int[][] newArray = new int[6][2];
int index = 0;
for (int i = 0; i < numList.length;) {
int count = 0;
for (int x = 0; x < numList.length; x++)
if (numList[x] == numList[i]) count++;
newArray[index][0] = numList[i];
newArray[index][1] = count;
index++;
i += count;
}
for (int x = 0; x < newArray.length; x++) {
for (int i = 0; i < newArray[0].length; i++)
System.out.print(newArray[x][i] + " ");
System.out.println();
}
This way, you don't have to deal with imports as in the other answers (and this is shorter), but this only works if you have ordered numbers. There are some good sorting algorithms out there, though.
Edit: I changed it so that it can take numbers in any order of any size.
int[] numList = { 6, 6, 5, 5, 4, 4, 3, 2, 1, 1, 1, 7, 6, 5, 7, 8, 65, 65, 7 };
int[][] newArray = new int[1][2];
int index = 0;
for (int i = 0; i < numList.length;) {
try {
int count = 0;
boolean isUnique = true;
for (int x = 0; x < i; x++)
if (numList[x] == numList[i]) {
isUnique = false;
break;
}
if (isUnique) {
for (int x = 0; x < numList.length; x++)
if (numList[x] == numList[i]) count++;
newArray[index][0] = numList[i];
newArray[index][1] = count;
index++;
}
i++;
} catch (ArrayIndexOutOfBoundsException e) {
int tmpArray[][] = newArray;
newArray = new int[tmpArray.length + 1][tmpArray[0].length];
for (int row = 0; row < tmpArray.length; row++)
for (int col = 0; col < 2; col++)
newArray[row][col] = tmpArray[row][col];
}
}
for (int x = 0; x < newArray.length; x++) {
for (int i = 0; i < newArray[0].length; i++)
System.out.print(newArray[x][i] + " ");
System.out.println();
}
So, at this point, it would probably be shorter to use the maps from the other answer. The only benefit of my second answer not worrying about imports.
private Map<Integer, Integer> segregateArray(List<Integer> list) {
Map<Integer, Integer> result = new HashMap<>();
for (Integer i : list) {
if (result.containsKey(i)) {
result.put(i, result.get(i) + 1);
} else {
result.put(i, 1);
}
}
return result;
}
This should work. If you still need to return array use this:
private int[][] segregateArray(int[]list) {
Map<Integer, Integer> resultHelper = new HashMap<>();
for (int i : list) {
if (resultHelper.containsKey(i)) {
resultHelper.put(i, resultHelper.get(i) + 1);
} else {
resultHelper.put(i, 1);
}
}
int[][] result = new int[resultHelper.size()][2];
int arrayIterator=0;
for(Integer key : resultHelper.keySet())
{
result[arrayIterator][0]=key;
result[arrayIterator][1]=resultHelper.get(key);
arrayIterator++;
}
return result;
}
In the real life project you probably should avoid implementing a functionality like this yourself using a low level array mechanism (you added an extensive test suite, didn't you? :) and opt for one of available libraries.
In Java 8 this can be done nicely using closures similarly to what has been described here: Count int occurrences with Java8.
In Java 7 and earlier I would use one of the collection libraries such as Guava, which contains a Multiset collection delivering exactly what you're after.

Categories

Resources