ArrayIndexOutOfBoundsException for unknown reason - java

I'm writing a program that creates a maze as a 2d array. I've run into a hiccup, and that is ArrayIndexOutOfBoundsException. It is pointing to maze[0][0] = "S" in the drawMaze method. I'm scratching my head at this, I have no idea why it's throwing an error.
import java.util.Random;
public class LA2_MazeSolver {
private int rows;
private int cols;
private String[][] maze = new String[rows][cols];
LA2_MazeInput mi = new LA2_MazeInput();
public void setNumRows(int numRows) {
this.rows = numRows;
}
public void setNumCols(int numCols) {
this.cols = numCols;
}
public int getNumRows() {
return this.rows;
}
public int getNumCols() {
return this.cols;
}
public void drawMaze() {
Random r = new Random();
maze[0][0] = "S";
maze[rows - 1][cols - 1] = "D";
int limit = ((rows * cols) / 3);
for (int i = r.nextInt(limit) + 1; i < limit; i++) {
maze[r.nextInt(rows) - 1][r.nextInt(cols) - 1] = "#";
}
for (int i = 0; i < maze.length; i++) {
for (int c = 0; c < maze[0].length; c++) {
if (!(maze[i][c].matches("#")) && !(maze[i][c].matches("S")) && !(maze[i][c].matches("D"))) {
maze[i][c] = Integer.toString(r.nextInt(100) + 1);
}
}
}
}
public void printMaze() {
}
/*public boolean isSolvable() {
return solveMazeRecursively(this.rows, this.cols);
}
private boolean solveMazeRecursively(int row, int col) {
}*/
public void printResult() {
}
}

It's simple. You are getting the Array Index Out of Bound exception because you are exceeding the array boundaries.
I've run into a hiccup, and that is ArrayIndexOutOfBoundsException. It is pointing to "maze[0][0] = "S";"
You have declared maze in the following block
private int rows;
private int cols;
private String[][] maze = new String[rows][cols];
Note that you are specifying a size of 'rows' and 'cols' for 'maze'. But these values are 0 and 0 respectively. See that you are not giving a value to rows and cols at the time of initialization. So the default value of int primitives declared as class members is 0.
To fix this problem, initialize rows and cols to a value greater than 0.

In Java, you can't make a definition like private String[][] maze = new String[rows][cols]; outside of the constructor. At that point in the the code, the value for row and col have not been defined and so something like private String[][] maze = new String[rows][cols]; won't have well defined behaviour (row and col may in fact be 0, who knows).
Try instead something like this:
private int row;
private int col;
private String[][] maze;
public LA2_MazeSolver(int row, int col) {
this.row = row;
this.col = col;
maze = new String[row][col]
}
Now when you create a LA2_MazerSolver object, you will dynamically create an array of the correct size to use (for example solver = new LA2_MazeSolver(row, col)).

Related

Java fill int [][] array from property.file

I want to program a pacmanstyle maze game in Java.
for the maze i am using a property file, in which coordinates are stored (i.e. x=1, y=5 -> wall) as strings in following format: 79,13=0 79,12=0 79,11=0.
I want to create the mazegrid using a 2d array: int [][] maze.
i know how to load in a property file. My problem however is, I have no idea how to first extract the string variables out of the property and second the proper way to fill the array.
public final class Labyrinth {
private int i;
private int j;
private static int [][] maze;
private String p;
private String l;
public void setMaze(int x, int y){
x = this.i;
y = this.j;
}
public static int[][] getMaze(){
return maze;
}
public Labyrinth(int rows, int cols) throws IOException{
try (FileInputStream in = new FileInputStream("level.properties")) {
Properties p1 = new Properties();
p1.load(in);
p = p1.getProperty("Height");
l = p1.getProperty("Width");
cols = parseInt(p);
rows = parseInt(l);
maze = new int[rows][cols];
for (i=0; i < rows; i++){
for(j=0; j < cols; j++){
setMaze(parseInt(p1.getProperty('ValueX,ValueY')),
parseInt(p1.getProperty('ValueX,ValueY')));
}
}
}
}
}
Any helpfull thought will be highly appreciated!
i have no idea how to first extract the string variables out of the .property and second the proper way to fill the array.
What do you mean by extracting string variables? A property file is simply a list of key-value pairs. In your case, the key is x,y and the value is apparently indicating some object in the maze.
You could try reading the keys like this:
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
int value = parseInt(p1.getProperty(i + "," + j); // Get the value of (i,j)
maze[i][j] = value; // Assign the value to the maze
}
}

how to print an empty 2d array without getting a nullpointerexception

I am relatively new to Java and for a school project I need to print a 2D array. The base for this project is to print it with values null. But I can't put this into a for loop without getting a java.lang.NullPointerException. Can anybody help?
private int ROWS;
private int COLUMNS;
private int WIDTH;
private String[][] sheet;
private String[][] values;
private int precision;
public SpreadSheet(int rows, int cols, int width, int precision) {
this.ROWS = rows;
this.COLUMNS = cols;
/*this.WIDTH = width;
this.precision = precision;*/
}
public void printSheet(){
for (int i = 0; i < sheet.length; i++) {
for (int j = 0; j < sheet[i].length; j++) {
System.out.println(sheet);
}
System.out.println("\n");
}
}
The main :
import java.util.Scanner;
public class DemoSpreadSheet {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
SpreadSheet sh = new SpreadSheet(4, 6, 15, 2);
sh.printSheet();
}
}
Make a small change to the SpreadSheet function:
public SpreadSheet(int rows;int cols;int width;int precision)
{
this.Sheet=new String[rows][cols];
/*creates an array with 4 rows and 6 columns..(assuming this is what you wanted to do)*/
}
There is also an error in your print sheet function:
System.out.println(Sheet); //illogical
/*sheet does not print the content of the array Sheet*/
Change this to:
System.out.println(Sheet[i][j]);
/*this will print null */
you need to initialisé your arrays.
sheet = new String[rows][cols]
This is an exemple you have other errors in you class.
This will do it (including better format):
public void printSheet(){
for (int i = 0; i < sheet.length; i++) {
for (int j = 0; j < sheet[i].length; j++) {
System.out.print(sheet[i][j] + " ");
}
System.out.println();
}
}
However, you have not assigned a length to your sheet. That means, at some point (at the constructor most likely) you have to define:
sheet = new String[rows][cols];

How would I make a board using 3d generic array

How would I make a board using the 3d generic array that contains col, row, and the stack (contains 4, 3, 2, 1).
This is what I declared:
private int row, col, stack;
int[][][] array3Dboard = new int[row][col][stack];
I just having trouble how to make an board using the multidimensional.
public void initalized(int arg1){
this.playerID = arg1;
this.array3Dboard = new int[4][4][4];
//create a data structure for the current contents of the board and stacks.
}
Thanks.
You need to make sure the class with method initialized() has int[][][] array3Dboard declared as an instance variable.
You also need to write:
int row = 4;
int col = 4;
int stack = 4;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
for (int k = 0; k < stack; k++) {
array3Dboard[i][j][k] = 0; //replace 0 with some numerical value
}
}
}

Why am I receiving this NullPointerException?

I encounter a NullPointerException on clickCell[r][c] = false; and on new LifeGUI(new LifeModel(x, y, s); and can't fix it. Please explain why this problem occurs and how I may fix it.
Code:
public LifeModel(int rows, int cols, int cellSize) {
row = rows;
col = cols;
cSize = cellSize;
for (int r = 0; r < row; r++) {
for ( int c = 0; c < col; c++) {
clickCell[r][c] = false;
}
}
}
public static void main(int x, int y, int s) {
new LifeGUI(new LifeModel(x, y, s));
}
You haven't shown where the clickcell array was declared, but likely you have declared it but not initialized it. You may have
boolean[][] clickcell;
but need:
boolean[][] clickcell = new boolean[rows][cols];
where rows and cols represent the size of the array you need.
You have to create the array object
boolean [][] clickCell = new boolean[rows][cols];
Add this command before the for loop.
More info here
If clickCell is declared somewhere else, the command should be:
clickCell = new boolean[rows][cols];
Or as GriffeyDog suggests, add the new boolean[rows][cols] at the place where you declare the array, depending on the logic of your program.

getting error StringIndexOutOfBoundsException: String index out of range [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am trying to build a matrix with row and column having values such as "aaa" for aligning purposes. but when I run it I get an error. below is my code
public class compute_matrix {
static String seq1="aaa";
static String seq2="aaa";
static int[][] matrix;
static int max_row;
static int max_col;
private static int match_reward=1;
private static int mismatch_penalty= -1;
private static int gap_cost= -1;
private static boolean case_sensitive;
private static boolean isCaseSensitive() {
return case_sensitive;
}
private static int max(int ins, int sub, int del, int i) {
if (ins > sub) {
if (ins > del) {
return ins > i? ins : i;
} else {
return del > i ?del : i;
}
} else if (sub > del) {
return sub> i ? sub : i;
} else {
return del > i ? del : i;
}
}
protected char sequence[];
public static void main(String args[]){
int r, c, rows, cols, ins, sub, del, max_score;
rows = seq1.length()+1;
cols = seq2.length()+1;
matrix = new int [rows][cols];
// initiate first row
for (c = 0; c < cols; c++)
matrix[0][c] = 0;
// keep track of the maximum score
max_row = max_col = max_score = 0;
// calculates the similarity matrix (row-wise)
for (r = 1; r < rows; r++)
{
// initiate first column
matrix[r][0] = 0;
for (c = 1; c < cols; c++)
{
sub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c));
ins = matrix[r][c-1] + scoreInsertion(seq2.charAt(c));
del = matrix[r-1][c] + scoreDeletion(seq1.charAt(r));
// choose the greatest
matrix[r][c] = max (ins, sub, del, 0);
if (matrix[r][c] > max_score)
{
// keep track of the maximum score
max_score = matrix[r][c];
max_row = r; max_col = c;
}
}
}
}
private static int scoreSubstitution(char a, char b) {
if (isCaseSensitive())
if (a == b)
return match_reward;
else
return mismatch_penalty;
else
if (Character.toLowerCase(a) == Character.toLowerCase(b))
return match_reward;
else
return mismatch_penalty;
}
private static int scoreInsertion(char a) {
return gap_cost;
}
private static int scoreDeletion(char a) {
return gap_cost;
}
public char charAt (int pos)
{
// convert from one-based to zero-based index
return sequence[pos-1];
}
}
and my error is displaying this
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.charAt(String.java:695)
at compute_matrix.main(compute_matrix.java:67)
Java Result: 1
rows = seq1.length()+1;
cols = seq2.length()+1;
matrix = new int [rows][cols];
and then later:
for (c = 1; c < cols; c++)
{
//when c == cols-1, it is also `seq2.length()`
//the access to seq2.charAt(c) will cause this exception then.
sub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c));
ins = matrix[r][c-1] + scoreInsertion(seq2.charAt(c));
del = matrix[r-1][c] + scoreDeletion(seq1.charAt(r));
In the above loop, when c == cols-1, it is also seq2.length(), the access to seq2.charAt(c) will cause this exception then.
You initialize the number of rows and cols to length() + 1, while you later iterate from 0 to length (inclusive), while the string contain only length() chars - from 0 to n exclusive.
If you are a C programmer in your past - I assume you are expecting a \0 terminator at the end of the string. In java you don't have those - since String is an object - you can hold a field to indicate its exact length. Meaning the last char in the string, is actually the last character there.
in line 60 of your code
sub = matrix[r-1][c-1] + scoreSubstitution(seq1.charAt(r),seq2.charAt(c));
max value for r is 4 so when you look up for seq.charAt(3) there is nothingso it shows index out of bound
I refactored your code into more canonical java.
The things I've changed:
The class is now called SimilarityMatrix, a more appropriate, self documenting name
variable declarations now happen where they get used as opposed to at the top of main
The work is now done in an instance of the class rather than the main method
I used the built in Math.max(int, int) instead of rolling my own
I removed a lot of unnecessary nested if statements. Java's short circuit evaluation helps here
Since both r and c as well as r+1 and c+1 are used frequently in your calculation loop, I track both
I removed many of the dependencies on static state (made many things instance variables)
Static state that remains is all final now (I made them constants)
Used more java-y variable names (java people really like their camel case)
public class SimilarityMatrix
{
public static final int matchReward = 1;
public static final int mismatchPenalty = -1;
public static final int gapCost = -1;
private int[][] matrix;
private int maxRow = 0;
private int maxCol = 0;
private boolean caseSensitive = false;
SimilarityMatrix(String s1, String s2, boolean dontIgnoreCase)
{
this(s1, s2);
caseSensitive = dontIgnoreCase;
}
SimilarityMatrix(String s1, String s2)
{
int rows = s1.length() + 1;
int cols = s2.length() + 1;
matrix = new int[rows][cols];
int max_score = 0;
for (int x = 0; x < cols; x++)
{
matrix[0][x] = 0;
matrix[x][0] = 0;
}
for (int r = 0, rp1 = 1; rp1 < rows; ++r, ++rp1)
{
for (int c = 0, cp1 = 1; cp1 < rows; ++c, ++cp1)
{
int sub = matrix[r][c] + scoreSubstitution(s1.charAt(r), s2.charAt(c));
int ins = matrix[rp1][c] + scoreInsertion(s2.charAt(c));
int del = matrix[r][cp1] + scoreDeletion(s1.charAt(r));
// choose the greatest
matrix[rp1][cp1] = Math.max(Math.max(ins, sub), Math.max(del, 0));
if (matrix[rp1][cp1] > max_score)
{
// keep track of the maximum score
max_score = matrix[rp1][cp1];
maxRow = rp1;
maxCol = cp1;
}
}
}
}
public static void main(String args[])
{
SimilarityMatrix me = new SimilarityMatrix("aaa", "aaa");
System.out.println(me.getMaxRow() + " " + me.getMaxCol());
}
private int scoreSubstitution(char a, char b)
{
if ((a == b && caseSensitive) || Character.toLowerCase(a) != Character.toLowerCase(b))
return matchReward;
else
return mismatchPenalty;
}
public int getMaxRow()
{
return maxRow;
}
public int getMaxCol()
{
return maxCol;
}
private int scoreInsertion(char a)
{
return gapCost;
}
private int scoreDeletion(char a)
{
return gapCost;
}
}

Categories