im attempting to test a program in java and i am getting an array index out of bounds exception that i dont believe should be thrown. have a look at this code and tell me if im missing something? eclipse is telling me the error is being thrown in the location where i have added a comment to show it
class maze{
private int cols; // number of columns in maze
private int rows; // number of rows in maze
private String name;
private weightedGraph<Integer> graph;
private dijkstra solution;
public char[][] mazeStore;
public maze(String filename){
try{
FileReader r = new FileReader(filename);
Scanner s = new Scanner(r);
this.rows = s.nextInt();
this.cols = s.nextInt();
this.name = filename;
this.mazeStore = new char[(2*rows)+1][(2*cols)+1];
String line = s.nextLine();
for(int k = 0; k < ((2*rows)+1); k++){
char[] temp = line.toCharArray();
for(int i = 0; i < temp.length; i++){
mazeStore[k][i] = temp[i];
line = s.nextLine();
}
}
graph = new weightedGraph<Integer>(rows*cols);
for(int y = 1; y < 2*rows; y++){
for(int x = 1; x < 2*cols; x++){
if((x % 2 == 1) && (y % 2 == 0)){
if(mazeStore[x][y] != '-'){ // <<<<<<<<<<<<<<THIS IS WHERE THE ERROR IS THROWN
int label = (x - 1) + (x / 2);
graph.addEdge(label, label+cols, 1);
graph.addEdge(label+cols, label, 1);
}
}
if((x % 2 == 0) && (y % 2 == 1)){
if(mazeStore[x][y] != '|'){
int label = ((x - 1) + (x / 2)) + (y / 2);
graph.addEdge(label, label+1, 1);
graph.addEdge(label+1, label, 1);
}
}
}
}
this.solution = new dijkstra(graph, 0);
}
catch(FileNotFoundException e){
System.err.println("FileNotFoundException: " + e.getMessage());
}
You initialized array
new char[(2*rows)+1][(2*cols)+1]
but iterating it
for(int y = 1; y < 2*rows; y++){//y row iterator
for(int x = 1; x < 2*cols; x++){//x col iterator
so it should be
mazeStore[y][x] not mazeStore[x][y]
you have youre varaibles out of order. youre outter most loop is based on rows but youre using it in the array you initialized to be the size of columns
Related
I want to search through a 2d object array and separate the objects based on an object class field, test 1 and test 2 respectively. I then want to write the 2d array's object's indices to two 1d arrays as x,y. I would like to have two pairs of two 1d arrays for each object, so that I can calculate the distance between the test 1 and test 2 object.
My problem/Question
When I run a loop on one of the 1d arrays to print their values to check them, they are filled with a bunch of zeros and they shouldn't be. I included comments in the code to help clarify.
public class gameboard2 {
public static void main(String[] args) {
Character2 objectArray[][] = new Character2[8][8];
int test1X1[] = new int[100];
int test1Y1[] = new int[100];
int test2X2[] = new int[100];
int test2Y2[] = new int[100];
int junkX1Array[] = new int[100];
int junkY1Array[] = new int[100];
for (int row = 0; row < objectArray.length; row++){
for(int col = 0; col < objectArray.length; col++){
if (row <= 1 && col <= 7){
objectArray[row][col] = new Character2();
objectArray[row][col].setType("Test1");
objectArray[row][col].setIdTest1(row,col);
objectArray[row][col].objectFlag = true;
}
else if ((row == 6 || row == 7) && (col <= 7)){
objectArray[row][col]= new Character2();
objectArray[row][col].setType("Test2");
objectArray[row][col].setIdTest2(row,col);
objectArray[row][col].objectFlag = true;
}
else {
objectArray[row][col]= new Character2();
objectArray[row][col].setType("Test3");
}
}
}
for (int x = 0; x < objectArray.length; x++){
for (int y = 0; y < objectArray.length; y++ ){
if (objectArray[x][y].getType().compareTo("Test1") == 0){
test1X1[x] = x;
test1Y1[y] = y;
}
if (objectArray[x][y].getType().compareTo("Test2") == 0){
test2X2[x] = x;
test2Y2[y] = y;
System.out.println(test2X2[x]);
//Arrays are filled with 2d array object indices and printed as they are filled. These values appear correct. However when you print from the array (see below) its filled with a bunch of zeros.
}
else
junkX1Array[x] = x;
junkY1Array[y] = y;
}
}
System.out.print("Now the newly created array will be printed");
// Array is printed. Values differ.
for (int b = 0; b < test2X2.length; b++)
{
System.out.println(test2X2[b]);
}
}
}
//
This is the object class.
public class Character2 {
private String id;
private String type;
boolean objectFlag = false;
public void setType(String AssignType) {
type = AssignType;
}
public String getType(){
return type;
}
public String getId(){
return id;
}
public void setIdTest1(int row, int col){
id = ("Test1" + " row: " + row + " col: " + col);
}
public void setIdTest2(int row, int col){
id = ("Test2" + " row: " + row + " col: " + col);
}
}
I think the problem here is that you are using a same index(x, y) for test1x1, test1Y1, test2X2, test2Y2 arrays. try using different index name for those arrays. because I think they are 4 different arrays.
for example :
int i=0;j=0;k=0;l=0;
for (int x = 0; x < objectArray.length; x++){
for (int y = 0; y < objectArray.length; y++ ){
if (objectArray[x][y].getType().compareTo("test1") == 0){
test2X2[i] = x;
test2Y2[j] = y;
i++;j++;
}
if (objectArray[x][y].getType().compareTo("test2") == 0){
test1X1[k] = x;
test1Y1[l] = y;
k++;l++;
}}}
Ok. Mast.mangesh was correct, he just didn't have the full context. You are indexing into your test arrays with x and y but you aren't adding values to your test arrays at every x and y. They should have their own index that is incremented only when you add something to the test array itself, which brings me to my next suggestion. Why are you using arrays here? Why not use something more robust, like ArrayList? You would have avoided that all along...
public static void test(){
Character2 objectArray[][] = new Character2[8][8];
ArrayList<Integer> x1 = new ArrayList<>();
ArrayList<Integer> y1 = new ArrayList<>();
ArrayList<Integer> x2 = new ArrayList<>();
ArrayList<Integer> y2 = new ArrayList<>();
ArrayList<Integer> junkx = new ArrayList<>();
ArrayList<Integer> junky = new ArrayList<>();
for (int row = 0; row < objectArray.length; row++){
for(int col = 0; col < objectArray.length; col++){
if (row <= 1 && col <= 7){
objectArray[row][col] = new Character2();
objectArray[row][col].setType("Test1");
objectArray[row][col].setIdTest1(row,col);
objectArray[row][col].objectFlag = true;
}
else if ((row == 6 || row == 7) && (col <= 7)){
objectArray[row][col]= new Character2();
objectArray[row][col].setType("Test2");
objectArray[row][col].setIdTest2(row,col);
objectArray[row][col].objectFlag = true;
}
else {
objectArray[row][col]= new Character2();
objectArray[row][col].setType("Test3");
}
}
}
for(Character2[] c2: objectArray){
for(Character2 c: c2){
System.out.print(" " + c.getType() );
}
System.out.println();
}
for (int x = 0; x < objectArray.length; x++){
for (int y = 0; y < objectArray.length; y++ ){
if (objectArray[x][y].getType().compareTo("Test1") == 0){
x1.add(x);
y1.add(y);
}
if (objectArray[x][y].getType().compareTo("Test2") == 0){
x2.add(x);
y2.add(y);
}
else{
junkx.add(x);
junky.add(y);
}
}
}
System.out.print("Now the newly created array will be printed");
for(int i : y2){
System.out.println(i);
}
}
I'm working on a couple of Project Euler problems and want to test my solution. My recursive function never ends even with reachable base cases.
in a 20x20 grid I am using x and y coordinates to navigate up and left to find the number of paths from (19,19) to (0,0). My base case is to return 1 when we reach (0,0). Otherwise I add the current count to the recursive call.
Function:
private static int numPaths(int x, int y, int pathsFound)
{
if(x == 0 && y == 0)
return 1;
else
{
if(x > 0)
{
pathsFound += numPaths(x - 1, y, pathsFound);
}
if(y > 0)
{
pathsFound += numPaths(x, y - 1, pathsFound);
}
}
return pathsFound;
}
Main:
int x = 19;
int y = 19;
System.out.println("Answer: " + numPaths(x, y, 0));
Is there a flaw in my recursive logic, or is just taking a very long time to compute? If you know the solution to this Euler problem, please do not post it.
https://projecteuler.net/problem=15
So if anyone is interested, I looked into memoization and came up with an elegant solution without recursion.
Function:
private static BigInteger numberPaths(ArrayList<ArrayList<BigInteger>> grid)
{
for(int i = 0; i <= 20; ++i)
{
for(int j = 0; j <= 20; ++j)
{
int x = j;
int y = i;
if(x - 1 < 0 || y - 1 < 0)
{
grid.get(x).set(y, BigInteger.ONE);
}
else
{
BigInteger topVal = grid.get(x - 1).get(y);
BigInteger leftVal = grid.get(x).get(y - 1);
grid.get(x).set(y, topVal.add(leftVal));
}
}
}
return grid.get(20).get(20); //the solution
}
Main:
ArrayList<ArrayList<BigInteger>> grid = new ArrayList<>();
for(int i = 0; i <= 20; ++i)
{
ArrayList<BigInteger> column = new ArrayList<>();
for(int j = 0; j <= 20; ++j)
{
column.add(BigInteger.valueOf(0));
}
grid.add(column);
}
System.out.println("Answer: " + numberPaths(grid));
I have a 3x4 matrix represented by a 2D array:
. 0 1 2 3
0 a c f i
1 b e h k
2 d g j l
and my approach to traverse the diagonal slice was to treat each slice as a sum, like this:
a = (0+0) = 0
b,c = (0+1),(1+0) = 1
d,e,f = (0+2),(1+1),(2+0) = 2
g,h,i = (1+2),(2+1),(3+0) = 3
j, k = (2+2),(3+1) = 4
l = (3+2) = 5
However, my code right now prints it in the opposite way that I want it to, which is from upper right to bottom left.
Current Output is:
acbfedihgkjl
Desired Output is:
abcdefghijkl
for (int sum = 0; sum <= numRows + numColumns - 2; sum++) {
for (int i = 0; i < numRows; i++) {
int j = sum - i;
if ((i >= 0 && i < numRows) && (j >= 0 && j < numColumns)) {
System.out.print(array[i][j]);
}
}
}
Can somebody point me in the right direction on how to fix my code to get the output that I want?
While it isn't very pretty, I think this will do it:
int i = 0;
int j = 0;
while (true) {
System.out.println("" + array[i][j]);
--i;
++j;
if (i < 0) {
if (j == numCols)
break;
i = Math.min(j, numRows - 1);
j = Math.max(j - numCols + 2, 0);
} else if (j >= numCols) {
if (i == numRows - 2)
break;
i = numRows - 1;
j = Math.max(j + 2 - numCols + i, 0);
}
}
int i = 0;
int j = 0;
int n = 0;
int x = 3;
int y = 4;
int newSize = Math.max(x,y) * Math.max(x,y);
while(n < newSize){
if(i <= x && j <= y)
System.out.println(array[i][j]);
n++;
if(i == 0) {
i = n:
j = 0;
} else {
--i;
++j;
}
}
package program2;
import java.util.*;
import java.io.*;
import java.io.CharArrayReader;
public class Program2 {
public static void main(String[] args) {
try {
String filename = args[0]; //reads command line argument 1 as filename
Scanner File = new Scanner(new File(filename)); //reads filename into program,and opens it for analysis
File.useDelimiter(System.getProperty("line.seperator"));
ArrayList<String> list = new ArrayList<>(); //creates an array list to store chars to transfer for reading from the file
while (File.hasNext()) {
list.add(File.next()); //adds each char letter to the list
}
File.close();//closes file stream
char[][] array1 = new char[10][20];
for (int i = 0; i < list.size(); i++) {
array1[i] = list.get(i).toCharArray(); //converts array list -> char array
}
int[] CountA = new int[200];
CountA = CharSearch(array1, 'A');
int[] CountB = new int[200];
CountB = CharSearch(array1, 'B');
int[] CountC = new int[200];
CountC = CharSearch(array1, 'C');
int totalA = 0;
int totalB = 0;
int totalC = 0;
int totalgroupsA = 0;
int totalgroupsB = 0;
int totalgroupsC = 0;
for (int i = 0; i > CountA.length; i++) {
if (CountA[i] != 0) {
totalA += CountA[i];
totalgroupsA++;
}
}
for (int i = 0; i > CountB.length; i++) {
if (CountB[i] != 0) {
totalB += CountB[i];
totalgroupsB++;
}
}
for (int i = 0; i > CountC.length; i++) {
if (CountC[i] != 0) {
totalC += CountC[i];
totalgroupsC++;
}
}
System.out.println(filename);
for (int i = 0; i> array1.length; i++){
for (int j = 0; j> array1.length; j++){
System.out.println(array1[i][j]);
if (array1[i][j] == array1[i][20])
System.out.println("\n");
}
}
System.out.println();
System.out.println("The number of groups of A is: " + totalgroupsA);
System.out.println("The number of groups of B is: " + totalgroupsB);
System.out.println("The number of groups of C is: " + totalgroupsC);
if (totalA > totalB && totalA > totalC) {
System.out.println("The largest group is " + totalA);
} else if (totalB > totalA && totalB > totalC) {
System.out.println("The largest group is " + totalB);
} else if (totalC > totalB && totalC > totalA) {
System.out.println("The largest group is " + totalC);
}
} catch (FileNotFoundException e) {
System.out.println("File is not found: " + e.getMessage());//catches and sends out an error message
}
}
static int[] CharSearch(char[][] array1, char a) {
int w = 10;
int h = 20;
int[] rst = new int[w * h];
int count = 0;
int next_region = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1.length; j++) {
if (array1[i][j] == a) {
continue;
}
count += 1;
int k = 0;
boolean connected = false;
//if connected to the left
if (j > 0 && array1[i][j - 1] == array1[i][j]) {
count += 1;
connected = true;
}
//if connected upwards
if (i > 0 && array1[i - 1][j] == array1[i][j] && (connected = false)) {
count += 1;
connected = true;
}
if (!connected) {
k = next_region;
rst[k] = count;
next_region++;
}
}
}
return rst;
}}
So I am getting a nullpointerexception and I wanna know where in my program there is a nullpointer exception? I tried switching stuff over to make more sense but it still doesn't work... Please help. There are of course a couple of more things that it says:
Exception in thread "main" java.lang.NullPointerException
at java.util.regex.Pattern.<init>(Pattern.java:1336)
at java.util.regex.Pattern.compile(Pattern.java:1022)
at java.util.Scanner$1.create(Scanner.java:411)
at java.util.Scanner$1.create(Scanner.java:409)
at sun.misc.LRUCache.forName(LRUCache.java:70)
at java.util.Scanner.useDelimiter(Scanner.java:1195)
at program2.Program2.main(Program2.java:13)
Your NullPointerException originates from this line:
File.useDelimiter(System.getProperty("line.seperator"));
Note you have a typo in the word "seperator" - it's supposed to be "separator" (a after the p). Because of this typo, you're trying to get property that doesn't exist, which returns null. Then, you use this value in File.userDelimiter, which expects a not-null value, and fails with the aforementioned exception.
These are the key lines in the stack trace:
at java.util.Scanner.useDelimiter(Scanner.java:1195)
at program2.Program2.main(Program2.java:13)
The program failed at line 13 in Program2. From what you posted, it looks like line 13 is this:
File.useDelimiter(System.getProperty("line.seperator"));
Which then corresponds to the next error - useDelimiter is failing. What is the value you are passing into this method? Are you sure it's non-null, and valid input for the useDelimiter method? What is System.getProperty("line.seperator") returning?
Note: seperator is a typo - the word is actually separator
You are given a 2D array as a string and a word via keyboard. The word
can be in any way (all 8 neighbors to be considered) but you can’t use
same character twice while matching. Return word's first and last
character's index as (x,y). If match is not found return -1.
That's the question. I'm having trouble with searching. I tried that:
int x=0,y=0;
for(int f=0; f<WordinArray.length; f++){
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
if(matrix[i][j].equals(WordinArray[f])){
x=i; y=j;
System.out.print("("+x+","+y+")");
}
}
}
}
But, That code is not working as it is supposed to. How else I can write this searching code?
Referring to Sixie's code
Assuming this is a valid input/output to your program?
Size:
4x4
Matrix:
a b c d
e f g h
i j k l
m n o p
Word: afkp
(0,0)(3,3)
I edited your code, so that it should work for input on this form (it is case sensitive at the moment, but can easily be changed by setting .toLowerCase()
Scanner k = new Scanner(System.in);
System.out.println("Size: ");
String s = k.nextLine();
s.toUpperCase();
int Xindex = s.indexOf('x');
int x = Integer.parseInt(s.substring(0, Xindex));
int y = Integer.parseInt(s.substring(Xindex + 1));
System.out.println("Matrix:");
char[][] matrix = new char[x][y];
for (int i = 0; i < x; i++) {
for (int p = 0; p < y; p++) {
matrix[i][p] = k.next().charAt(0);
}
}
System.out.print("Word: ");
String word = k.next();
int xStart = -1, yStart = -1;
int xEnd = -1, yEnd = -1;
// looping through the matrix
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
// when a match is found at the first character of the word
if (matrix[i][j] == word.charAt(0)) {
int tempxStart = i;
int tempyStart = j;
// calculating all the 8 normals in the x and y direction
// (the 8 different directions from each cell)
for (int normalX = -1; normalX <= 1; normalX++) {
for (int normalY = -1; normalY <= 1; normalY++) {
// go in the given direction for the whole length of
// the word
for (int wordPosition = 0; wordPosition < word
.length(); wordPosition++) {
// calculate the new (x,y)-position in the
// matrix
int xPosition = i + normalX * wordPosition;
int yPosition = j + normalY * wordPosition;
// if the (x,y)-pos is inside the matrix and the
// (x,y)-vector normal is not (0,0) since we
// dont want to check the same cell over again
if (xPosition >= 0 && xPosition < x
&& yPosition >= 0 && yPosition < y
&& (normalX != 0 || normalY != 0)) {
// if the character in the word is not equal
// to the (x,y)-cell break out of the loop
if (matrix[xPosition][yPosition] != word
.charAt(wordPosition))
break;
// if the last character in the word is
// equivalent to the (x,y)-cell we have
// found a full word-match.
else if (matrix[xPosition][yPosition] == word
.charAt(wordPosition)
&& wordPosition == word.length() - 1) {
xStart = tempxStart;
yStart = tempyStart;
xEnd = xPosition;
yEnd = yPosition;
}
} else
break;
}
}
}
}
}
}
System.out.println("(" + xStart + "," + yStart + ")(" + xEnd + ","
+ yEnd + ")");
k.close();
I think you need to plan your algorithm a bit more carefully before you start writing code. If I were doing it, my algorithm might look something like this.
(1) Iterate through the array, looking for the first character of the word.
(2) Each time I find the first character, check out all 8 neighbours, to see if any is the second character.
(3) Each time I find the second character as a neighbour of the first, iterate along the characters in the array, moving in the correct direction, and checking each character against the word.
(4) If I have matched the entire word, then print out the place where I found the match and stop.
(5) If I have reached the edge of the grid, or found a character that doesn't match, then continue with the next iteration of loop (2).
Once you have your algorithm nailed down, think about how to convert each step to code.
If I understood your question right. This is a quick answer I made now.
int H = matrix.length;
int W = matrix[0].length;
int xStart = -1, yStart = -1;
int xEnd = -1, yEnd = -1;
String word = "WordLookingFor".toLowerCase();
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
if (matrix[i][j] == word.charAt(0)) {
int tempxStart = i;
int tempyStart = j;
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int k = 0; k < word.length(); k++) {
int xx = i+x*k;
int yy = j+y*k;
if(xx >= 0 && xx < H && yy >= 0 && yy < W && (x != 0 || y != 0)) {
if(matrix[xx][yy] != word.charAt(k))
break;
else if (matrix[xx][yy] == word.charAt(k) && k == word.length()-1) {
xStart = tempxStart;
yStart = tempyStart;
xEnd = xx;
yEnd = yy;
}
} else
break;
}
}
}
}
}
}
A little trick I used for checking all the 8 neighbors is to use two for-loops to create all the directions to go in:
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
if(x !=0 || y != 0)
System.out.println(x + ", " + y);
}
}
This creates
-1, -1
-1, 0
-1, 1
0, -1
0, 1
1, -1
1, 0
1, 1
Notice: All but 0,0 (you don't want to revisit the same cell).
The rest of the code is simply traversing though the matrix of characters, and though the whole length of the word you are looking for until you find (or maybe you don't find) a full match.
This time the problem is that how could I print word's first and last
letter's indexes. I tried various ways like printing after each word
was searched. But, all of them didn't work. I am about to blow up.
int[] values = new int[2];
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
if(Character.toString(word.charAt(0)).equals(matrix[i][j]) == true || Character.toString(ReversedWord.charAt(0)).equals(matrix[i][j]) == true ){
System.out.print("("+ i + "," +j+")");
//First letter is found.Continue.
for(int p=1; p<word.length(); p++){
try{
for (int S = -1; S <= 1; S++) {
for (int SS = -1; SS <= 1; SS++) {
if(S !=0 || SS != 0)
if(matrix[i+S][j+SS].equals(Character.toString(word.charAt(p))) && blocksAvailable[i+S][j+SS] == true ||
matrix[i+S][j+SS].equals(Character.toString(ReversedWord.charAt(p))) && blocksAvailable[i+S][j+SS] == true) {
values[0] = i+S;
values[1] = j+SS;
blocksAvailable[i+S][j+SS] = false;
}
}
}
}catch (ArrayIndexOutOfBoundsException e) {}