Reputation: 342
so I'm relatively new to Java (I'm taking AP java at my school currently) and I am trying to develop a recursive algorithm to solve an n*n board and I feel I am very close but not quite there yet. I have everything written out to traverse my dictionary to find if the letters I am sending it are words or not etc. My algorithm is to have the starting letter be (n,p) in my array, send those cordinates to another method that will go in every direction to find all possible combinations. once all combinations starting with (n,p) have been found, I would increment p until it got to the end of the row then i would increment n and start p from 0 again. (I only go through half the letters because the combinations are the same backwards and forwards)
The part i have trouble with is the recursive sequence because once I go over a certain position on the board i want to mark it to make sure i never go over it again for the rest of the sequence. It doesn't fully work and i was wondering if anyone could tell me why/help me write a better algorithm. Thanks in advance
public void AllLetters(int n, int p, int x, int y,String word, String MyLetteres[][]){
int temp=0;
int StartLetter =(int)(Math.pow(MyLetteres.length,2));
while(temp<StartLetter)//runs through every letter
{
if(temp==0)
getPaths(p, n,x,y,word, MyLetteres);
else if(temp%(MyLetteres.length-1)==temp){
getPaths(p, n+1,x,y,word, MyLetteres);
}
else {
getPaths(p+1, 0,x,y,word, MyLetteres);
}
if(temp==(StartLetter/2-1)){
temp=StartLetter;
}
temp++;
}
}
public void getPaths(int p, int n, int x, int y,String word, String MyLetteres[][]){
if( x ==p-1 && y == n-1){//reach the (n,p) point
System.out.print("");
}else if( x >= MyLetteres.length || y >= MyLetteres.length||x < 0 || y < 0){//out of bounds
return;
}else {
if(x+1<MyLetteres.length&&!MyLetteres[x+1][y].equals("0")){//up{
word=word+""+MyLetteres[x+1][y];
Check(word);//function that checks if it is a word
reverse(word);//checks its a word backwards (for efficenicy)
MyLetteres[x+1][y]="0";//marking that I've used this position
System.out.print("1");//debugging purposes
getPaths(n,p, x +1, y,word , MyLetteres);
}
if(x-1>0&&!MyLetteres[x-1][y].equals("0")){//down
word=word+""+MyLetteres[x-1][y];
Check(word);
reverse(word);
MyLetteres[x-1][y]="0";
System.out.print("2");
getPaths(n,p, x -1, y ,word, MyLetteres);
}
if(y+1<MyLetteres.length&&!MyLetteres[x][y+1].equals("0")){//right
word=word+""+MyLetteres[x][y+1];
Check(word);
reverse(word);
MyLetteres[x][y+1]="0";
System.out.print("3");
getPaths(n, p,x , y +1,word, MyLetteres);
}
if(y-1>0&&!MyLetteres[x][y-1].equals("0")){//left
word=word+""+MyLetteres[x][y-1];
Check(word);
reverse(word);
MyLetteres[x][y-1]="0";
System.out.print("4");
getPaths(n,p, x , y -1,word, MyLetteres);
}
if(x+1<MyLetteres.length&&y+1<MyLetteres.length&&!MyLetteres[x+1][y+1].equals("0")){//right, up
word=word+""+MyLetteres[x+1][y+1];
Check(word);
reverse(word);
MyLetteres[x+1][y+1]="0";
System.out.print("5");
getPaths(n,p, x +1, y +1,word, MyLetteres);
}
if(x-1>0&&y-1>0&&!MyLetteres[x-1][y-1].equals("0")){//down, left
word=word+""+MyLetteres[x-1][y-1];
Check(word);
reverse(word);
MyLetteres[x-1][y-1]="0";
System.out.print("6");
getPaths(n,p, x-1 , y -1,word, MyLetteres);
}
if(x-1>0&&y+1<MyLetteres.length&&!MyLetteres[x-1][y+1].equals("0")){//down, right
word=word+""+MyLetteres[x-1][y+1];
Check(word);
reverse(word);
MyLetteres[x-1][y+1]="0";
System.out.print("7");
getPaths(n,p, x+1, y-1, word,MyLetteres);
}
if(x+1<MyLetteres.length&&y-1>0&&!MyLetteres[x+1][y-1].equals("0")){//up, left
word=word+""+MyLetteres[x+1][y-1];
Check(word);
reverse(word);
MyLetteres[x+1][y-1]="0";
System.out.print("8");
getPaths(n, p,x-1 , y +1, word,MyLetteres);
}
}
}
Upvotes: 0
Views: 910
Reputation: 16364
You write 0's into MyLetteres
to keep the recursion from looping back on itself. But once the recursive call has returned, you need to restore the original letter that was in that position. Otherwise the search can only look at each position once, over all the branches it tries.
(Also, you could simplify your code a lot by looping through a list of (x, y) offsets rather than having a separate if
statement for each one)
Edit:
int[][] offsets = { {-1, -1}, {0, -1}, {1, -1},
{-1, 0}, {1, 0},
{-1, 1}, {0, 1}, {1, 1} };
for(int[] off : offsets) {
nx = x + off[0];
ny = y + off[1];
if(nx < 0 || ny < 0 || nx >= MyLetteres.length || ny >= MyLetteres[nx].length) {
continue;
}
String letter = MyLetteres[nx][ny];
if(letter.equals("0")) {
continue;
}
MyLetteres[nx][ny] = "0";
Check(word + letter);
reverse(word + letter);
getPaths(n,p, nx, ny, word + letter, MyLetteres);
MyLetteres[nx][ny] = letter;
}
Upvotes: 1