Another depth first search in java issue - java

I am tying to implement a depth first search algorithm in java to find the best way to move in a quadratic matrix. I am avoiding to create "unnecessary" objects, i.e object just to hold (X,Y) positions.
Am I forgetting something? I am running it with starting points of (0,0) and with objective of (4,5). What happens is an infinite loop.
int x = this.move_to_x;
int y = this.move_to_y;
Stack X = new Stack();
Stack Y = new Stack();
Stack visited_X = new Stack();
Stack visited_Y = new Stack();
X.push(this.current_x);
Y.push(this.current_y);
while(!X.empty()){
int tmp_x = (int)X.pop();
int tmp_y = (int)Y.pop();
if(tmp_x == x && tmp_y == y){
System.out.println("best way found!");
return;
}
//there is only 8 possible ways to go (the neighbors)
for(int a = -1; a < 2; a++){
for(int b = -1; b < 2; b++){
if(a == 0 && b == 0){
break;
}
if(visited_X.search(tmp_x + a) == -1 && visited_Y.search(tmp_y + b) == -1){
X.push(tmp_x + a);
Y.push(tmp_y + b);
visited_X.push(tmp_x + a);
visited_Y.push(tmp_y + b);
System.out.println("added x " + tmp_x + a + " y " + tmp_y + b);
}
}
}
}

I can see several problems:
1) In the following:
if(a == 0 && b == 0){
break;
}
you should be using continue rather than break.
2) The following:
if(visited_X.search(tmp_x + a) == -1 && visited_Y.search(tmp_y + b) == -1){
is incorrect: the (tmp_x, tmp_y) pair has to be present at the same index in visited_X/visited_Y.
3) You should add the starting position to visited_{X,Y}.
4) Algorithmically, I don't see any reason to think that your method would return the shortest path.
5) The reason your code ends up in (an almost) infinite loop is that you don't check for the matrix boundaries.

Related

What is a good way to output why an object won't go through all of the "if" statements?

I am making a program that checks to see if an elements positive and negative charges are able to combine to make 0. A thing i want to do is output the reasons why the two elements are not able to combine. But it is more difficult than i expected. for example if sodium were trying to combine with copernicium, it would output this:
Sodium doesn't combine with Copernicium:
Both valence charges have same polarity.
One or more elements is man-made.
but i can not think of a way to implement this into my code.
here is my code:
public void combine(Element element){
if ((element.getValence() > 0 && valence < 0) || (element.getValence() < 0 && valence > 0)) { //one element needs a positive valence, and one needs a negative valence
if (valence != 0 && element.getValence() != 0) { //checks to see if valence is not equal to 0
if (natural == true && element.isNatural() == true) { //checks to see if both elements are natural
for (int x = 1; x <= 4; x++) {//bruteforce the atoms to see if they both add up to 0.
for (int y = 1; y <= 4; y++) {
if ((valence * x) + (element.getValence() * y) == 0) {
System.out.println(name + " combines with " + element.getName() + " to form " + symbol + "" + x + "" + element.getSymbol() + "" + y);
}
}
}
}
}
}
}
Thanks for any help!
The way to do this is to add else clauses for each if that return an appropriate message.
if ((element.getValence() > 0 && valence < 0) || (element.getValence() < 0 && valence > 0)) { //one element needs a positive valence, and one needs a negative valence
{
// the inner tests
}
else
{
System.out.println("The elements are both positive or both negative");
}
}
This should get you started in the right direction.

Java Infix to Postfix method using queue and stack not working

I'm trying to convert infix to postfix expressions in Java, but somehow it's not reading it in correctly or there might be something wrong with my queue implementation. I tried debugging but I can't see where I went wrong.
Inputs:
2 + 3
4 + 5+6
(7+8) * 9
Output:
2+
4+5
78
Correct outputs would be:
23+
45+6+
78+9*
This is my code:
public int Prior (char c) {
if (c == '/' || c == '*')
return 2;
else if (c == '+' || c == '-')
return 1;
else
return 0;
}
public String convertIn2Post() throws StackException, QueueException{
infix = infix.trim();
for(int i = 0; i < infix.length(); i++) {
if(Character.isDigit(infix.charAt(i))) {
expQueue.enqueue(infix.charAt(i) + "");
}
if (infix.charAt(i) == '(') {
opStack.push(infix.charAt(i) + "");
}
if (infix.charAt(i) == ')') {
while(opStack.peek().equals("(") != true) {
expQueue.enqueue(opStack.pop());
}
opStack.pop();
}
if ( infix.charAt(i) == '+' ||
infix.charAt(i) == '-' ||
infix.charAt(i) == '/' ||
infix.charAt(i) == '*' ) {
if(opStack.isEmpty()){
opStack.push(infix.charAt(i) + "");
}
while(Prior(infix.charAt(i)) <= Prior(opStack.peek().charAt(0))){
expQueue.enqueue(opStack.pop());
if(opStack.isEmpty()){
break;
}
}
}
}
while(!opStack.isEmpty()){
expQueue.enqueue(opStack.pop());
}
for(int y = 0; y < expQueue.size(); y++){
postfix += expQueue.dequeue();
}
return "postfix:: " + postfix;
}
First off, one simple bug in the program is the loop that will dequeue everything. Notice, that each time the loop is run, it checks that
y < expQueue.size()
but, everytime an element is dequeued from the queue, this value is decreasing. So, if the size starts at 6, the program will run for y = 0, size = 6, y = 1, size = 5, y = 2 size = 4, y = 3 size = 3 and that is where it stops. So change this to a while loop:
while(!expQueue.isEmpty())
Next, the algorithm for converting infix to postfix says that if the opstack is empty, to push the operator, which is correct in the code. Then it says that if it is not empty, if the one just found is of higher priority than the one on top of the stack, to add that one to the top of the stack, otherwise pop the top and add the new operator to the stack; this can be done as follows:
if(opStack.isEmpty()){
opStack.push(infix.charAt(i) + "");
}
else
{
String peek = opStack.peek();
if(Prior(peek.charAt(0)) >= Prior(infix.charAt(i)))
{
expQueue.add(opStack.pop());
opStack.push(infix.charAt(i) + "");
}
else
{
opStack.push(infix.charAt(i) + "");
}
}

Avoid out of bounds exception in 2D array

I'm trying to solve a problem which uses a 2D array, the problem of a rat in a maze.
While checking the conditions trying to compile, it finds an Array index out of bounds exception... how can I check the values so it doesn't go out of the array bounds?
static void solveMaze(){
int nSteps = 0; // Number of steps.
int x = 0; int y = 0; // Starting point.
boolean mazeCompleted = false;
while (!mazeCompleted){
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
mazeCompleted = true;
else if(maze.mazeMatrix[x+1][y] == 0){ // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
else if(maze.mazeMatrix[x-1][y] == 0){ // Move left.
maze.mazeMatrix[x-1][y] = 2;
x--; nSteps++;
}
else if(maze.mazeMatrix[x][y+1] == 0){ // Move down.
maze.mazeMatrix[x][y+1] = 2;
y++; nSteps++;
}
else if(maze.mazeMatrix[x][y-1] == 0){ // Move up.
maze.mazeMatrix[x][y-1] = 2;
y--; nSteps++;
}
}
maze.printMatrix();
System.out.println("Maze COMPLETE! - With a total of " + nSteps + " steps.");
}
Tried before with two "for" loops to prevent the out of bounds but I just can't go diagonal in this problem.
You have a pretty crucial bug in your program. You will never reach the end of the maze!
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
references indices that are out of bounds! It should be
if(x == maze.mazeMatrix.length - 1 && y == maze.mazeMatrix.length - 1)
You also need to check to see whether you can & should move before you try to move there. I.E. :
while (!mazeCompleted){
boolean moveRight = (x + 1 < mazeMatrix.length && maze.mazeMatrix[x+1][y] == 0 ? true : false);
boolean moveLeft = (x - 1 >= 0 && maze.mazeMatrix[x-1][y] == 0 ? true : false);
boolean moveUp = (y + 1 < mazeMatrix[x].length && maze.mazeMatrix[x][y+1] == 0 ? true : false);
boolean moveDown = (y - 1 >= 0 && maze.mazeMatrix[x][y-1] == 0 ? true : false);
And:
else if(moveRight) { // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
etc. Although it does seem like this is something that should be solved recursively, as if there are any loops in the maze you will end up getting stuck and infinite looping.

How to end my recursion

I need to program a method to solve a maze (2-dimensional array). I need to stay directly left of the wall at all times and my method should end when either I've reached the exit point (which is always at the same position) or when there is no solution possible (and, after running through the maze I'm back at the entry point).
I was able to do all that, no problems, I can visually ensure that it's doing what I want it to do (we've got some other methods from our instructor which output the visuals) and my console debug output is right as well.
This is the relevant code:
public static void main(String[] args) {
maze = generateMaze(10,10);
walk(1,0,0);
}
public static void walk(int x, int y, int direction) {
System.out.println("x = " + x + " y = " + y); //debug output
draw(x,y,maze); //draws current position
if (x == maze.length-1 && y == maze[1].length-2) { //terminate when reached exit
System.out.println("Geschafft!");
return;
}
if (x == 1 && y == 0 && direction == 3) { //terminate when at starting point again (no solution)
System.out.println("Keine Lösung möglich.");
return;
}
if (direction == 0) { //go down
if (maze [x][y+1]) {
walk(x,y,1);
}
walk(x,y+1,2);
}
if (direction == 1) { //go right
if(maze [x+1][y]) {
walk(x,y,3);
}
walk(x+1,y,0);
}
if (direction == 2) { //go left
if(maze [x-1][y]) {
walk(x,y,0);
}
walk(x-1,y,3);
}
if (direction == 3) { //go up
if(maze[x][y-1]) {
walk(x,y,2);
}
walk(x,y-1,1);
}
}
There's just one problem: how do I end my recursion correctly? This is what I get form the console:
x = 1 y = 0
x = 1 y = 1
x = 1 y = 1
x = 1 y = 2
and so on...
x = 8 y = 8
x = 9 y = 8
Geschafft!
x = 8 y = 9
x = 8 y = 9
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at maze.MazeSolution.walk(MazeSolution.java:26)
at maze.MazeSolution.walk(MazeSolution.java:39)
and some more of that
I do understand the error, the recursion obviously doesn't end where I want it to and x or y are increased and try to use an index in the array that isn't there.
Why doesn't the recursion end with the return statement, when either of these situations come true:
if (x == maze.length-1 && y == maze[1].length-2) { //terminate when reached exit
System.out.println("Geschafft!");
return;
}
if (x == 1 && y == 0 && direction == 3) { //terminate when at starting point again (no solution)
System.out.println("Keine Lösung möglich.");
return;
}
What do I need to do to end it correctly?
I greatly appreciate your help, show some love for a beginner and tell me what to do.
Add to the beginning
public static void walk(int x, int y, int direction) {
System.out.println("x = " + x + " y = " + y); //debug output
if (x >= 10 || x < 0 || y >= 10 || y < 0) return;
Look at your returns and where you may return to. You can return in the middle of your enclosing function which has other calls to walk, without the guards to ensure they're not called.
I recommend re-implementing your logic; think about having if/else pairs to ensure mutual exclusion.
Why don't you simply return true or false and react on it?
So basically you add to your two end cases return true; for code ended.
if(walk(...)) return true;

How do I do recursive multiplication when one or both of the factors is/are negative?

public static int multiply2(int num1, int num2) {
if (num1 == 0 || num2 == 0) {
return 0;
}
else {
return num1 + multiply2(num1, num2 - 1);
}
}
I just realized that it would be fun to make a program that could determine the product of two numbers, one or both being negative. I want to do it using recursive multiplication (basically repeated addition). Could some one help me out? Thanks!
if (num1 == 0 || num2 == 0) {
return 0;
}
else if( num2 < 0 ) {
return - num1 + multiply2(num1, num2 + 1);
}
else {
return num1 + multiply2(num1, num2 - 1);
}
You would test if it's negative and subtract instead of add:
public static int multiply2(int num1, int num2) {
if (num1 == 0 || num2 == 0) {
return 0;
}
else if(num2 > 0){
return num1 + multiply2(num1, num2 - 1);
}
else{
return -num1 + multiply2(num1, num2 + 1);
}
}
else if (num1 < 0 || num2 < 0) {
int signum1 = num1 < 0 ? -1 : 1;
int signum2 = num2 < 0 ? -1 : 1;
return signum1 * signum2 * multiply(signum1 * num1, signum2 * num2);
} else {
Something like that
Note: there is a signum function and Math.abs can be used for signum * num
You will need to add if number is -ve. If you see we are adding only first number and for second number condition we have to reach is 0. So if negative do+1 if positive do -1
else if (num2 < 0)
return -num1 + multiply2(num1, num2 + 1);
else
return num1 + multiply2(num1, num2 - 1);
System.out.println(multiply2(5, -6));-->-30
System.out.println(multiply2(5, 6));-->30
Instead of dealing with it multiple times in the main recursion part, a better idea would be to handle it as an edge case and just convert it into a regular case since both the assignment and return will not occur until the mathematical operation has finished.
To do this, I converted y into a positive number and then negated the result of the function as a whole once the result has returned to the negative case.
Here's my solution:
private static int product(int x, int y) {
// Negative start edge case
if (y < 0) {
return -1 * product(x, y * -1);
}
// Edge case (only for speed)
if (y == 0 || x == 0) {return 0;}
// Base case
if (y == 1) {
return x;
}
// Recursion
return x + product(x, y-1);
}
It's worth noting that even with out the 0 edge case, the method would still work. In this case the method would just need to make a few more than necessary to get the result.
Testing has concluded that this method works with either parameter being 0 and/or negative.
public static int multiply2(int num1, int num2) {
if (num1 == 0 || num2 == 0) {
return 0;
}
else {
int sign2=(int)(Math.abs(num2)/num2);
return sign2*num1 + multiply2(num1,num2-sign2);
}
}
David Wallace's answer is good but if the input is (1,124) or (-1,124) the depth of recursion (number of times the method calls itself) will be 123, not very efficient. I would suggest adding a couple of lines to test for 1 or -1. Here's a full example:
public class Multiply {
public static void main(String[] args) {
System.out.print("product = " + multiply(1, 124) );
}
public static int multiply(int x, int y) {
System.out.println("Multiply called: x = " + x + ", y = " + y);
if (x == 0 || y == 0) {
System.out.println("Zero case: x = " + x + ", y = " + y);
return 0;
}
else if (x == 1 && y > 0) {
return y;
}
else if (y == 1 && x > 0) {
return x;
}
else if ( x == -1 && y > 0) {
return -y;
}
else if ( y == -1 && x > 0) {
return -x;
}
else if( y == -1 ) {
System.out.println("y is == -1");
return -x;
}
else if( x == -1 ) {
System.out.println("x is == -1");
return -y;
}
else if( y < 0 ) {
System.out.println("y is < 0");
return -x + multiply(x, y + 1);
}
else {
System.out.println("Last case: x = " + x + ", y = " + y);
return x + multiply(x, y - 1);
}
}
}
Output:
Multiply called: x = 1, y = 124
product = 124
Okay, so I am actually working on this one for homework. Recursive solutions implement - or use - a base case against which the need to continue is determined. Now, you might say, "What on Earth does that mean?" Well, in laymen's terms, it means we can simplify our code (and, in the real world, save our software some overhead) - about which I will explain, later. Now, a part of the issue is understanding some basic math, namely, a negative plus a negative is a negative or minus a positive ( -1 + -1 = -2) depending upon the math teacher to whom you speak (we'll see that come into play in the code, below).
Now, there is some debate to be had, here. About which I will write, later.
Here is my code:
public static int multiply(int a, int b)
{
if (a == 0)
{
return result;
}
else if (a < 0) // Here, we only test to see whether the first param.
// is a negative
{
return -b + multiply(a + 1, b); // Here, remember, neg. + neg. is a neg.
} // so we force b to be negative.
else
{
result = result + b;
return multiply(Math.abs(a - 1), b);
}
}
Notice there are a two things done differently, here:
The code above does not test the second parameter to see whether the second parameter is negative (a < 0) because of the mathematical principle in the first paragraph (see bold text in first paragraph). Essentially, if I know I am multiplying (y) by a negative number (-n), I know I am taking -n and adding it together y number of times; therefore, if the multiplicand or multiplier is negative, I know I can take either of the numbers, make the number negative, and add the number to itself over and over again, e.g. -3 * 7 could be written (-3) + (-3) + (-3) + (-3)... etc. OR (-7) + (-7) + (-7)
NOW HERE IS WHAT'S UP FOR DEBATE: That above code does not test to see whether the second number (int b) is 0, i.e. multiplying by 0. Why? Well, that's personal choice (sort of). The debate here must weigh the relative significance of something: the overhead for each choice (of either running an equals-zero test or not). If we do test to see if one side is zero, each time the recursive call to multiply is made, the code must evaluate the expression; however, if we do not test for equals zero, then the code adds a bunch of zeros together n number of times. In reality, both methods "weigh" the same - so, to save memory, I leave out the code.

Categories