Beginner 2D-Array out of bounds exception - java

I'm having some difficulties trying to figure out how to implement a second array to calculate the averages of my marks program.
I'm using 1 2D array to store the scores each student received on each assignment
(5 students, 4 assignments).
I have managed to get the Students average array working but when I go to calculate each individual assignment mark (combined total of the 5 students /5 ). I keep getting an Indexoutofbounds exception, Im very new to 2d arays and am still trying to figure out how to read them properly.
Heres my code:
import java.util.Scanner;
public class Marks
{
private String[] names;
private int[][] assignments;
private double[] stuAvgArray;
private double[] assignAvgArray;
public Marks()
{
names = new String[5];
assignments = new int[5][4];
stuAvgArray = new double[5];
assignAvgArray = new double[4];
}
public void getInput()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter 5 student names: ");
for(int i = 0; i < names.length; i++)
names[i] = input.nextLine();
for(int row = 0; row < assignments.length; row++)
{
System.out.println("Enter the 4 marks for: " + names[row]);
for(int col = 0; col < assignments[row].length; col++)
{
assignments[row][col] = input.nextInt();
stuAvgArray[row] += assignments[row][col];
}
stuAvgArray[row] = (stuAvgArray[row]/4);
}
for (int col = 0; col < assignments.length; col++)
{
for(int row = 0; row < assignments[col].length; row++)
assignAvgArray[row] += assignments[row][col];
assignAvgArray[col] = (assignAvgArray[col]/5);
}
}
public String toString()
{
String output = ("Student \t\t\t Marks \t\t\t\t Average \n" +
"Name \t\t\t\t out of 10 \t\t\t out of 10 \n" +
"\t\t A1 \t A2 \t A3 \t A4");
for(int i = 0; i < assignments.length; i++)
{
output = output + "\n" + names[i];
for(int col = 0; col < assignments[i].length; col++)
{
output = output + "\t " + assignments[i][col] + "\t ";
}
output = output + "\t\t" + stuAvgArray[i];
output = output + "\n" + assignAvgArray[i];
}
return output;
}
}
i've bolded where java says the error is coming from. I am trying to read in, store, and then calculate for the array spots [[(0,0),(1,0),(2,0),(3,0),(4,0)],[(0,1),(1,1),(2,1),(3,1),(4,1)..etc]]
what Im trying to ask is how can I create a loop that doesn't give me this exception, storing all the values of each column into separate spots, and dividing each number stored in the new array by 5 to give me the average.
if there's anything else I can do to help you understand my problem please let me know.
PS: This is what It's supposed to look like;
Student Marks Average
Name out of 10 out of 10
A1 A2 A3 A4
Joe Smith 8 9 10 4 7.75
Tommy Jones 9 9 8 5 7.50
Sara Lee 0 10 10 9 7.25
Bob Fowler 10 9 9 0 7.00
Jane Doe 10 10 10 10 10.00
**Average 7.40 9.40 9.40 5.60**
I've calculated the row average but the bolded column average is giving me grief

The following line is wrong:
for(int row = 0; row < assignments[col].length; col++)
You are using row and increment col instead. As a result, you are doing an out of bound error in the block of that loop.
Replace it by:
for(int row = 0; row < assignments[col].length; row++)
But I'm afraid this is not the only problem. According to the way you read the input, assignments is a 2D-array with the row number for the first dimension and the column number for the second dimension. However, you are mixing the dimension here. As a reminder, you code is:
for (int col = 0; col < assignments.length; col++)
{
for (int row = 0; row < assignments[col].length; row++) {
assignAvgArray[row] += assignments[row][col];
}
assignAvgArray[col] = (assignAvgArray[col]/5);
}
As you can see, you are using col to identify the row. assignments.length is the number of lines.
for (int col = 0; col < assignments[0].length; col++)
{
for (int row = 0; row < assignments.length; row++) {
assignAvgArray[row] += assignments[row][col];
}
assignAvgArray[col] = (assignAvgArray[col]/5);
}

for (int col = 0; col < assignments.length; col++)
{
for(int row = 0; row < assignments[col].length; row++)
assignAvgArray[row] += assignments[row][col];
assignAvgArray[col] = (assignAvgArray[col]/5);
}
}
assignments.length is 5 so col can become 4.
assignAvgArray.length is 4. When you are giving the aassignAvgArray col=4 it will throw an arrayoutofboundException.
fix it ,and if you still have an error comment under my answer.

Related

How to align output from an excel file?

''''Workbook wb = new Workbook("workbook.xlsx");
WorksheetCollection collection = wb.getWorksheets();
for (int worksheetIndex = 0; worksheetIndex < collection.getCount(); worksheetIndex++) {
Worksheet worksheet = collection.get(worksheetIndex);
System.out.println("People on Island: " + worksheet.getName());
System.out.println();
int rows = worksheet.getCells().getMaxDataRow();
int cols = worksheet.getCells().getMaxDataColumn();
Style st = wb.createStyle();
for (int i = 0; i <= rows; i++) {
for (int j = 0; j <= cols; j++) {
System.out.print(worksheet.getCells().get(i, j).getValue() + " ");
}
System.out.println();
System.out.println();
}
}
}''''
OUTPUT CURRENTLY:
People on Island: Sheet1
First Name Last name Gender Country Age Date
Dulce Bleoop Female Zimbabwe 43 2035-03-01T00:00:00
Sheeba Loadlee Female Sketchawan 24 3040-04-03T00:00:00
Jello Bamop Male Antarctica 32 2053-04-06T00:00:00
Barbara Slack Female Scandalousia 70 3203-03-12T00:00:00
You can do something like this:
//Code for reading data, not relevant for the solution
String my_string= """
People on Island: Sheet1
FirstName LastName Gender Country Age Date
Dulce Bleoop Female Zimbabwe 43 2035-03-01T00:00:00
Sheeba Loadlee Female Sketchawan 24 3040-04-03T00:00:00
Jello Bamop Male Antarctica 32 2053-04-06T00:00:00
Barbara Slack Female Scandalousia 70 3203-03-12T00:00:00""";
String[] split_string = my_string.split("\n\n");
String[][] finalString = new String[split_string.length][];
for (int i = 0; i < split_string.length; i++) {
finalString[i] = split_string[i].split(" ");
}
//Relevant code below
int spaceBetween = 25; //this variable decides the distance between each column
for (int i = 0; i < finalString.length; i++) {
for (int j = 0; j < finalString[i].length; j++) {
System.out.print(finalString[i][j]);
for (int k = 0; k < spaceBetween-finalString[i][j].length(); k++)
System.out.print(" ");
}
System.out.println("\n");
}
The output is:
People on Island: Sheet1
FirstName LastName Gender Country Age Date
Dulce Bleoop Female Zimbabwe 43 2035-03-01T00:00:00
Sheeba Loadlee Female Sketchawan 24 3040-04-03T00:00:00
Jello Bamop Male Antarctica 32 2053-04-06T00:00:00
Barbara Slack Female Scandalousia 70 3203-03-12T00:00:00
The Space between each column is decided by the variable spaceBetween.
In conclusion, you should be able to change the line
System.out.print(worksheet.getCells().get(i, j).getValue() + " ");
to
val = worksheet.getCells().get(i, j).getValue();
System.out.print(val);
for (int k = 0; k < spaceBetween-val.lenght(); k++)
System.out.print(" ");
where you choose a value for spaceBetween somewhere in the code.
If what you want is to align the output lines printed in console, you will have to loop over the fields two times. The first for getting whe length of each column and the second to print them correctly.
You can use a method that given a String pads it with whitespaces to the end:
public static String alignLeft(String str, int width) {
if (str.length() >= width) {
return str;
}
return alignLeft(str + " ", width);
}
Then, given the values of each cell as a String in a bidimensional array cells, doing the following:
int[] columnsWidths = new int[cells[0].length];
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
if (columnsWidths[j] < cells[i][j].length()) {
columnsWidths[j] = cells[i][j].length();
}
}
}
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
System.out.print(alignLeft(cells[i][j], columnsWidths[j]) + " ");
}
System.out.println();
}
Assuming you are using aspose, since you included the tag, you could use the export to array method:
....
int rows = worksheet.getCells().getMaxDataRow();
int cols = worksheet.getCells().getMaxDataColumn();
Object dataTable[][] = worksheet.getCells().exportArray(0, 0, rows, cols);
for (final Object[] row : dataTable) {
System.out.format("%15s%15s%15s%15s%15s%15s%n", row);
}
For left-aligned output change the print statement to
System.out.format("%-15s%-15s%-15s%-15s%-15s%-15s%n", row);
Of course 15 is just a random value I choosed, because I thought the max length of a cell value has 15 chars. change as you see fit. You could also for each column, check length of all strings in that column and take max string length in that column as column width for that column. Which could end for example in something like:
System.out.format("%-10s%-10s%-8s%-15s%-5s%-25s%n", row);

How to fix the following error java.lang.ArrayIndexOutOfBoundsException

I wanted to ask a question of code that has grated ja, I have the following code, I am going through a 10x5 array to fill it with number 1, to 49 for a primitive and the function that is responsible for making ticket gives me very rare errors. Index On Bound in theory the function would not have to go out of the way but I do not know what to do if someone can hit me.
// It is this part that gives me an error, I have a fly
int ,c=0;
int m[][]= new int[10][5];
for (int i=0;i<m.length;i++) {
for (int x=0;x<m.length;x++,i++) {
m[x][i]=c;
}
}
// This part of code I only have to check if the data output
// does them correctly
for(int i=0;i<m[0].length;i++) {
for(int x=0;x<m.length;x++) {
System.out.print(" "+m[i][x]+" ");
}
System.out.println(" ");
}
}
El error que me da es siguiente:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at provas/provas.main.main(main.java:11)
Looks like you want to fill given array with numbers from 1 to 49. So you have to pay attention on:
int[][] arr = new int[10][5] creates an int array with 10 rows and 5 columns
arr.length gives you a total rows amount
arr[0].length given you a total columns amount at row 0 (each row could have different length).
public static int[][] fillArray(int[][] arr) {
int i = 1;
for (int row = 0; row < arr.length; row++)
for (int col = 0; col < arr[row].length; col++)
arr[row][col] = i++;
return arr;
}
And finally to print an array:
public static void printArray(int[][] arr) {
for (int row = 0; row < arr.length; row++) {
for (int col = 0; col < arr[row].length; col++)
System.out.format("%3d", arr[row][col]);
System.out.println();
}
}
You original method could be like this:
int[][] arr = fillArray(new int[10][5]);
printArray(arr);

2D Array(Ragged) - Print Each Column Sum

I'm trying to calculate the column-wise sum of a 2D array.
For this 2D array:
int[][] array = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
I have no trouble printing each column sum.
Here is my code which does that
int total;
for (int col = 0; col < array[0].length; col++)
{
total = 0;
for (int row = 0; row < array.length; row++)
total += array[row][col];
System.out.println("Column " + col + " total: " + total);
}
But, for this ragged 2D array:
int[][] array = {{1,2},{5,6,7},{9,10,11,12}};
I can't seem to print the last two columns without getting an outofboundsexception error. Our professor hasn't really taught us the try and catch statements, so I'm assuming that there must be a small adjustment of some sort. However, I've already tampered with the above code to print the last two columns but no luck...
Any ideas?
Try this:
int total;
int max = //This is the max number of column one row can have
for (int col = 0; col < max; col++)
{
total = 0;
for (int row = 0; row < array.length; row++)
if(col < array[row].length)//Check for row length here.
total += array[row][col];
System.out.println("Column " + col + " total: " + total);
}
Basically, you need to check for the length of the row first, before accessing its element.
To find max:
int max = 0;
for(int i = 0; i < array.length; i++)
max = Math.max(array[i].length, max);
You don't need to catch any exceptions. First you should find out what is the longest row in the 2D array (you need a preliminary loop for that).
Suppose it's x. Then you iterate in your outer loop from 0 to x-1, and in your inner loop, before accessing array[row][col], you make sure that array[row].length > col.
Below is the proper code of the program:: I have learnt from above helping material but I was getting error due to codes were in bits and pieces and especially max value were taken the max (if we need lower number of max in the next counter then this program was failing)
package arrayPractice;
public class SumColumArray {
public static void main (String [] args){
int [][] matrix = new int [5][];
matrix[0] = new int[2];
matrix[1] = new int[3];
matrix[2] = new int[4];
matrix[3] = new int[2];
matrix[4] = new int[1];
int total = 0;
int max = 0;
for(int row = 0; row < matrix.length; row++){
max = matrix[row].length; // Variable Length of Column Accessing
System.out.println(max);
for(int column = 0; column < max; column++){
total = 0;
matrix[row][column] = (int)(Math.random() * 100);
if(column < matrix[row].length);
total += matrix[row][column];
System.out.println("Column " + column + " total: " + total);
}
}
}
}
Your professor may not accept this because he hasn't taught you this (yet), but the most elegant solution is to let Java make the low-level looping decisions for itself. You can do this with the for-each loop:
int total = 0;
int iterator = 0; // this variable is only necessary if you need to know which row you're in
for (int[] row : array) {
int sum = 0;
for (int item : row) {
sum += item;
}
System.out.println("Column " + iterator + " total: " + sum);
total += sum;
iterator++;
}
System.out.println(total);
The way it works is that you specify an array and the type of its elements. So an int[][] is an array of int[], that's why you specify for (int[] row : array). You can read it as "for each one-dimensional row[] in this two-dimensional array[][]". Within the loop, you nest another loop over each int of the row[].

The values of the columns of my 2D array are averaging wrong with out of order inputs

I'm working on a code to produce a 2D array to hold user inputted values. I made a averaging function in the "print array for loop"but it messes up such as when column input (3 1 2) gives an average of output of (2 6 4). All the values of the array were set to 2 for testing. I can't figure out what is wrong with the loop. I'm new to java so I'm sorry if the answer is something obvious.
The table printed should look like this with row(3) and columns(3 1 2):
A:2.0 2.0 2.0 [3.0]
B:2.0 [2.0]
C:2.0 2.0 [2.0]
where the bracketed term holds the average and the 2.0 are the values held by the column.
The code:
// creating 2d array
System.out.print("Please enter number of rows : ");
rows = Keyboard.nextInt();
Keyboard.nextLine();
while (rows < 0 || rows >= 10) {
System.out.print("ERROR:Out of range, try again : ");
rows = Keyboard.nextInt();
Keyboard.nextLine();
}
double[][] figures = new double[rows][num];
for(int t = 0; t < rows; t++) {
rLetter = (char)((t)+'A');
System.out.print("Please enter number of positions in row " + rLetter + " : ");
columns = Keyboard.nextInt();
Keyboard.nextLine();
while((columns < 0) || (columns >= 8)) {
System.out.print("ERROR:Out of range, try again : ");
columns = Keyboard.nextInt();
Keyboard.nextLine();
}
figures[t] = new double[columns];
}
// filling the array
for(int row = 0; row < figures.length; ++row) {
for(int col = 0; col < figures[row].length; ++col) {
figures[row][col] = 2.0;
}
}
// printing the array
for(int row=0; row<figures.length; ++row) {
// printing data row
group = (char)((row)+(int)'A');
System.out.print(group+" : ");
for(int col=0; col<figures[row].length; ++col) {
sum += figures[row][col];
average = sum/figures[row].length;
System.out.print(" "+figures[row][col]);
System.out.print(" ");
}
System.out.printf("%1$5s","["+average+"]");
System.out.println();
}
}
PS: its a minor question, I'm using %1$5s to keep the bracket term 5 spaces from the printed columns, but I was wondering if there is a way to keep them all at the same length.
You need to add
sum = 0;
after
for(int row=0; row<figures.length; ++row) {
otherwise the totals are wrong when you calculate the average.
To pad out a string, there's a good answer on here already How can I pad a String in Java?. Look at the 2nd answer.
int minLen = 20;
String s = myformat(value, length);
int diff = minLen - s.length;
System.out.printf("%1$" + diff + "s", s);
Where String s is your formatted string using your above "[" + average + "]" stuff. The idea is that you have a minimum length string to work with so that your positioning is always the same.

Working With 2D Arrays in Java [duplicate]

This question already has answers here:
Summing Up A 2D Array
(3 answers)
Closed 9 years ago.
I'm trying to repost this question but with more clarification. Given my code below, I wish to output the total of each column and each row. The row totals should be to the right of the last element in that particular row and the column total should be below the final element in a given column. Please see the comment in the beginning of my program to understand what I wish my output to be. How could I go about doing this? Also I want to print out the main diagonal of a given user-inputted array. So in the code below the main diagonal would be outputted as {1,3,5}. Thank you!
/*
1 2 3 Row 0: 6
2 3 4 Row 1: 9
3 4 5 Row 2: 12
Column 0: 6
Column 1: 9
Column 2: 12
*/
import java.util.Scanner;
import java.util.Arrays;
public class Test2Darray {
public static void main(String[] args) {
Scanner scan =new Scanner(System.in); //creates scanner object
System.out.println("How many rows to fill?"); //prompts user how many numbers they want to store in array
int rows = scan.nextInt(); //takes input for response
System.out.println("How many columns to fill?");
int columns = scan.nextInt();
int[][] array2d=new int[rows][columns]; //array for the elements
for(int row=0;row<rows;row++)
for (int column=0; column < columns; column++)
{
System.out.println("Enter Element #" + row + column + ": "); //Stops at each element for next input
array2d[row][column]=scan.nextInt(); //Takes in current input
}
for(int row = 0; row < rows; row++)
{
for( int column = 0; column < columns; column++)
{
System.out.print(array2d[row][column] + " ");
}
System.out.println();
}
System.out.println("\n");
}
}
}
int[] colSums = new int[array2d.length];
int[] mainDiagonal = new int[array2d.length];
for (int i = 0; i < array2d[0].length; i++) {
int rowSum = 0;
for (int j = 0; j < array2d.length; j++) {
colSums[j] += array2d[i][j];
rowSum += array2d[i][j];
System.out.print(array2d[i][j] + " ");
if (i == j) mainDiagonal[i] = array2d[i][j];
}
System.out.println(" Row " + i + ": " + rowSum);
}
System.out.println();
for (int i = 0; i < colSums.length; i++)
System.out.println("Column " + i + ": " + colSums[i]);
System.out.print("\nMain diagonal: { ");
for (Integer e : mainDiagonal) System.out.print(e + " ");
System.out.println("}");

Categories