Keep getting ArrayIndexOutOfBoundsException - java

I am trying to make an array that outputs a pattern depending on how many rows and columns I give it for the input and I receive an error when it gets to the third method. I understand that the array begins at index zero and if i input (0 0) for the matrix it's out of bounds but i have no idea how to fix the problem. Thank you for the help!
Here is my code for the first class:
public class Transpose {
public static int [][] createPatterned2DArray(int rows, int cols)
{
int [][] table = new int [rows] [cols];
for (int numRows = 0; numRows < table.length; numRows++){
for (int numCols = 0; numCols < table[0].length; numCols++){
table [numRows][numCols] = 10 + rows*(numRows +1) + numCols;
}
}
return table;
}
public static void print2DArray (int[][] matrix)
{
for (int row = 0; row < matrix.length; row++)
{
for (int col = 0; col < matrix[0].length; col++)
{
System.out.printf("%-4d",matrix[row][col]);
}
System.out.println();
}
}
public static void print2DArrayTransposed(int [][] matrix)
{
for (int row = 0; row < matrix[0].length; row++)
{
for (int col = 0; col < matrix.length; col++)
{
//try {
// if (matrix[0] == 0) {
// System.out.println(matrix[0][0]);
// throw new Exception();
System.out.printf("%-4d",matrix [col][row]);
// }
//catch (Exception e){
// System.out.print(e);
}
System.out.println();
}
}
}
Here is the second class:
import java.util.*;
public class TestTranspose extends Transpose {
public static void main(String[] args)
{
Scanner scan = new Scanner (System.in);
int rows = scan.nextInt();
int cols = scan.nextInt();
int [][] table = createPatterned2DArray(rows,cols);
print2DArray(table);
System.out.println();
print2DArrayTransposed(table);
System.out.println();
}
}
This is the error that I am getting and its driving me insane!
I can't seem to wrap my head around how to throw an exception or to make the output display nothing when i enter an input of (0 0) for the arrays. How can I correct this line of code that does not let me output an array of (0 0)?
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Transpose.print2DArrayTransposed(Transpose.java:32)
at TestTranspose.main(TestTranspose.java:13)

You can't safely do matrix[0].length without first ensuring that matrix.length != 0. In your other two methods, the outer loops on row take care of this.
But in print2DArrayTransposed it's your outer loop that's trying to do row < matrix[0].length; there's nothing to stop it trying to do that even when matrix.length == 0. You can address this in one of two ways: add this early bail-out at the top of print2DArrayTransposed:
if (matrix.length == 0)
return;
or change your outer loop on 'row' to:
for (row = 0; matrix.length > 0 && row < matrix[0].length; ++row)

Take a look at this line of code in the Transpose.print2DArrayTransposed() method:
for (int row = 0; row < matrix[0].length; row++)
You are trying to access the first element of matrix, but there is no element because the length is zero.
A 0x0 array is valid, so no need to disallow creating the array in the first place. My suggestion would just be to simply check at the start of the method if the length of matrix is zero, and if so, just return because there is nothing to print (or print some helpful message instead).
public static void print2DArrayTransposed(final int[][] matrix) {
if (matrix.length == 0) {
return;
}
//...
}

Related

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);

How to print first five elements of an matrix in Java

My goal is to implement the following method in parallel:
public static double[][] parallelAddMatrix(double[][] a, double[][] b), then test my program on randomly generated two lists of size 2000 x 2000. Finally I have to output the first 5 elements of matrix a and matrix b, and also the first five elements of the result matrix, which is what I'm having trouble with.
This is the part of my code where I create the first and second matrix.
public static void main(String[] args) {
int var1, var2;
final int matrices = 2000;
// creates first matrix
double[][] matrixA = new double[matrices][matrices];
for(var1 = 0; var1 < matrixA.length; var1++)
for (var2 = 0; var2 < matrixA[var1].length; var2++)
matrixA[var1][var2] = 1;
// creates second matrix
double[][] matrixB = new double[matrices][matrices];
for (var1 = 0; var1 < matrixB.length; var1++)
for (var2 = 0; var2 < matrixB[var1].length; var2++)
matrixB[var1][var2] = 1;
And then later created a function to create the result matrix...
public static double[][] parallelAddMatrix( double [][] a, double[][] b) {
//creates output matrix
double[][] resultMatrix = new double[a.length][a[0].length];
RecursiveAction task = new multiProcess(a, b, resultMatrix);
ForkJoinPool joinPool = new ForkJoinPool();
joinPool.invoke(task);
return resultMatrix;
}
How can I print out the first five elements for each of the three matrices?
I've tried stuff for the first and second matrix such as initializing var3, then under the "matrixA(orB)[var1][var2] = 1;", I put
for (var3 = 0; var3 < 5; var3++) {
System.out.println(var3);
}
and also tried
for (var3 = 0; var3 < 5; var3++) {
System.out.print(matrixA[var1][var2] + "");
}
System.out.println();
Please help on this, and please tell where it would be placed for each one (I might have trouble with brackets).
You'll need a nested for loop to iterate through the matrix, and a counter to see how many entries you've printed. Let's start with the easiest part: iterating over the matrix. I'll assume that the matrix is simply called matrix.
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.println(matrix[i][j]);
}
}
You probably already figured that out. Now we need a counter to count how many times we've printed out an entry from the matrix.
int num_printed = 0;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.println(matrix[i][j]);
num_printed ++;
}
}
Ok. So now we need to stop once we've reached the end. We can't just use one break statement, because, we have two for loops.
int num_printed = 0;
for (int i = 0; i < matrix.length; i++) { // iterate over the rows
for (int j = 0; j < matrix[i].length; j++) { // iterate over the columns
if (num_printed == 5) { // if we've already printed five items, stop
break;
} else { // otherwise, print the next item
System.out.println(matrix[i][j]);
num_printed ++; // increment the counter
}
}
if (num_printed == 5) { // so that we don't go to the next row
break;
}
}
It's worth noting that you could create your own separate method, and only use a return statement:
public void print_five_elements() {
int num_printed = 0;
for (int i = 0; i < matrix.length; i++) { // iterate over the rows
for (int j = 0; j < matrix[i].length; j++) { // iterate over the columns
if (num_printed == 5) { // if we've already printed five items, stop
return;
} else { // otherwise, print the next item
System.out.println(matrix[i][j]);
num_printed ++; // increment the counter
}
}
}
}
More Specialized Approach
This approach allows you to use matrices that have less than five columns. However, since your matrix is 2000x2000, you could go for a much simpler approach. Use zero as the first index, and then just iterate up to five. Just keep in mind that this won't work if you have less than five columns:
public void print_five_elements_for_wide_matrix() {
for (int i = 0; i < 5; i++) {
System.out.println(matrix[0][i]);
}
}
Since the matrices are of size 2000 x 2000, you do not need nested loops to display first 5 elements from each of them.
int i;
//Display first 5 elements of matrixA
for(i=0; i<5; i++) {
System.out.print(matrixA[0][i] + " ");
}
System.out.println();
//Display first 5 elements of matrixB
for(i=0; i<5; i++) {
System.out.print(matrixB[0][i] + " ");
}
System.out.println();
double[][] result = parallelAddMatrix(matrixA, matrixB);
//Display first 5 elements of result
for(i=0; i<5; i++) {
System.out.print(result[0][i] + " ");
}
System.out.println();
Note that the above loops print the first 5 elements of the first row (i.e. row at index, 0) of each matrix. However, if you want to print the first element of the first 5 rows, just swap the indices e.g.
System.out.println(matrixA[i][0] + " ");
Try this:
Think of the first set of brackets as the row and the second set as the column.
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
System.out.print(matrixA[row][col] + " ");
}
System.out.println();
}
Since "multi-dimensional" arrays are really arrays of arrays you can do it like this if you wanted to print out the whole matrix
for (double[] row : matrixA) {
System.out.println(Arrays.toString(row));
}
Because of this, each row can be a different length. So you may have to get the length to print them out like you first wanted to.
for (int row = 0; row < matrixA.length; row++) {
for (int col = 0; col < matrixA[row].length; col++) {
System.out.print(matrixA[row][col] + " " );
}
}
Rows of different length of a "2D" array are known as ragged-arrays.

How can I fix no line found error when using scanner in my code?

I keep getting this exception when I run my code:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Unknown Source)
at BattleshipCheck.generateGrid(BattleshipCheck.java:60)
here's my code:
public static int[][] generateGrid(Scanner in, int gridSize) {
int[][] grid = new int[gridSize][gridSize];
while(in.hasNextLine()) {
in.nextLine();
in.nextLine();
String[] currentLine = in.nextLine().split("\\s+");
for (int row = 0; row < gridSize; row++) {
for (int column = 0; column < gridSize; column++) {
grid[row][column] = Integer.parseInt(currentLine[column]);
}
}
}
return grid;
}
I'm trying to start reading from the third row so I used .nextLine twice and I'm thinking that's where my problem lies but I'm not sure how to fix it
Looks like you are ignoring the data in the file. It tells you how many lines there are. Also, there is no need for a while loop.
public static int[][] generateGrid(Scanner in) {
// Get gridSize from file
int gridSize = Integer.parseInt(in.nextLine());
int[][] grid = new int[gridSize][gridSize];
// Not sure what 2nd line is for
// I'm guessing it is the number of ships followed
// by the size of each ship
in.nextLine();
for (int row = 0; row < gridSize; row++) {
// Move this here
String[] currentLine = in.nextLine().split("\\s+");
for (int column = 0; column < gridSize; column++) {
grid[row][column] = Integer.parseInt(currentLine[column]);
}
}
return grid;
}
You still need to add error checking in case the file is malformed. Although I would leave as-is an let it throw an exception if there is a problem. Let the calling function deal with it.
If you want to start at the third row, call nextLine() before the while-Loop, not inside of it. Once you're at the last line, you try skipping two more lines, which dont exist. You'll also have to check whether the file actually has three lines before skipping two lines.
public static int[][] generateGrid(Scanner in, int gridSize) {
int[][] grid = new int[gridSize][gridSize];
if(in.hasNextLine())in.nextLine();
if(in.hasNextLine())in.nextLine();
while(in.hasNextLine()) {
String[] currentLine = in.nextLine().split("\\s+");
for (int row = 0; row < gridSize; row++) {
for (int column = 0; column < gridSize; column++) {
grid[row][column] = Integer.parseInt(currentLine[column]);
}
}
}
return grid;
}
int i=0;
public static int[][] generateGrid(Scanner in, int gridSize) {
int[][] grid = new int[gridSize][gridSize];
while(in.hasNextLine()) {
if(++i < 2) {
in.nextLine();
continue;
}
String[] currentLine = in.nextLine().split("\\s+");
for (int row = 0; row < gridSize; row++) {
for (int column = 0; column < gridSize; column++) {
grid[row][column] = Integer.parseInt(currentLine[column]);
}
}
}
return grid;
}

1-Dimensional array -> 2D array

So i'm a beginner;
The task is to convert a given string into the array, the string always has the first characcter as the amount of rows and the second character as the amount of columns.
My problem is to solve how to move the rest of the string 's' into the 2D array from the 1D array.
Thanks in advance!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] s = scanner.nextLine().split(" ");
int arows = Integer.parseInt(s[0]);
int acols = Integer.parseInt(s[1]);
int[][] cells = new int[arows][acols];
for (int col = 0; col < acols; col++){
for (int row = 0; row <= arows;row++){
cells[row][col] = Integer.parseInt(s[2]);
}
}
}
}
You need to implement a counter for your for-loops to iterate through the input string. What you are doing right now is to fill your 2D-Array with the third element of your string.
One solution would be to just declare a variable i = 2, and increment it for each pass of the inner for-loop.
int i = 2
for (int col = 0; col < acols; col++){
for (int row = 0; row < arows;row++){
cells[row][col] = Integer.parseInt(s[i]);
i++;
}
}
Edit: removed <= in row loop, changed the initial value of the index to 2
This is the solution, you have to put another iterator, and initialize it to 2, so to skip the first two elements of s[]
int i = 2;
for (int col = 0; col < acols; col++){
for (int row = 0; row < arows;row++){
cells[row][col] = Integer.parseInt(s[i]);
i++;
}
}

Java pyramid of numbers - version 2

I'm reading a book and before I go to next chapter, I want to solve every exercise from current one. I have a problem with creating this output (the number of rows must be between 11 and 20)
I almost have it, even when I think my code is pretty bad and I could get it in less lines.
public class piramide {
public static void main(String args[]){
int max, n;
max = 20;
n=1;
for (int min=11; min<=max; min++){
if (n>9) n-=10;
int x=n-1;
int x2=n-1;
int b=min-1;
for (int j=1; j<min; j++){
while (b<max-1) {
System.out.print(" ");
b++;
}
System.out.print(x);
x--;
if (x<0) x=9;
}
System.out.print("A"+n+"A");
for (int j=1; j<min; j++){
System.out.print(x2);
x2--;
if (x2<0) x2=9;
}
System.out.println();
n+=2;
}
}
}
This is my current code and this is the output:
0987654321A1A0987654321
21098765432A3A21098765432
432109876543A5A432109876543
6543210987654A7A6543210987654
87654321098765A9A87654321098765
098765432109876A1A098765432109876
2109876543210987A3A2109876543210987
43210987654321098A5A43210987654321098
654321098765432109A7A654321098765432109
8765432109876543210A9A8765432109876543210
The problem I'm having is that the left part of the pyramid should be reversed. For example in the first row it should start at 0 (from the A1A) and finish in 1 but it starts in 1 and finish in 0, any idea how can I turn it to the other side?
Thanks to all of you who helped me ^^.
Oh, and the caps A are just so I could find the number easier in the output.
Have you worked the problem out?
The code will be much easier to understand with a couple changes...
max, min, and especially the single letter variables like n should have names that help describe what they are. This may also help you think about the problem when you don't have to keep in mind what all those random letters mean.
n I will rename to rowIndex
max I will rename to totalRows
min I will rename to columnIndex
Starting with that we have
public static void main(String args[])
{
int totalRows = 20;
int rowIndex = 1;
int columnIndex = 1;
//we look ready to start at row 1, column 1!
}
Now, this section of your code:
for (int min=11; min<=max; min++){
if (n>9) n-=10;
int x=n-1;
int x2=n-1;
int b=min-1;
for (int j=1; j<min; j++){
while (b<max-1) {
System.out.print(" ");
b++;
}
You are setting min, or, the columnIndex, to start at 11, because that is the "middle" of the pyramid. Then you print out spaces to catch up to the columnIndex.
x = rowIndex - 1;
x2 = rowIndex - 1;
b = columnIndex - 1;
j and b are now like a second and third column index, which is catching up to the actual columnIndex
Look at this example of how your for loop works:
for (int j=1; j <min; j++) { // j = 1;
while (b<max-1) { // 10 < 19
System.out.print(" "); // print space
b++; // b = 11
// 11 < 19
// print space
// b = ...(*skip to the end*) 19
// j = 2
// b is still 19, doesn't print anything
// j = 3, etc.
}
System.out.print(x);
x--;
if (x<0) x=9;
}
In other words, j and b are unnecessary because we already have a columnIndex we can use. Let's do some more renaming of variables.
x I will rename to printValue
x2 will be unnecessary, we only need one printValue, However, I will be adding a totalColumns to the beginning of our main method.
So now our finished code will look like:
public static void main(String args[])
{
int totalRows = 20;
int totalColumns = (totalRows * 2) - 1; //added totalColumns, notice the number of columns increases by two with each row and we start with 1 column.
int rowIndex = 0;//easier for looping to start with zero
int columnIndex = 0;
int printValue = 0;
while (rowIndex < totalRows) // we will want to spin through every row
{
//notice there is no limit to the length of a variable name!
int numberOfValuesInRow = (rowIndex*2) + 1;
int numberOfSpacesToOffsetOnEachSide = (totalColumns - numberOfValuesInRow) / 2;
//Print Spaces before the numbers in this row
for (int i = 0; i < numberOfSpacesToOffsetOnEachSide; i++) //i is commonly used to stand for index in a single for loop
{
System.out.print(" ");
columnIndex++; //keep track of columnIndex so we know when we are at the middle of the columns
}
//Print numbers in this row
for (int i = 0; i < numberOfValuesInRow; i++)
{
if (columnIndex < (totalColumns/2) + 1) { //depending on columnIndex position, increase or decrease printValue
printValue++;
} else {
printValue--;
}
System.out.print(printValue%10); //Print printValue, the % will return the remainder of (printValue/10)
columnIndex++;
}
System.out.println(); //start next line
columnIndex = 0; //reset columnIndex for the next row
rowIndex++;
}
}

Categories