2016-07-29 10 views
1

Ich habe dieses Problem versucht und aus irgendeinem Grund ist es nicht richtig. Bei einem Array von Strings, finde heraus, wie viele mögliche Lösungen für das Labyrinth existieren, wo die Strings aus einem "R" (der Ratte), einem "C" (dem Käse), mehreren "X's" (Blöcke, die nicht passieren können) besteht. und "." (mögliche Wege). Die Aufgabe ist es, die Anzahl der möglichen Wege zu finden, die die Ratte nehmen kann, um an den Käse zu kommen, ohne jemals die (euklidische) Distanz zwischen sich und dem Käse zu erhöhen. Was mit meinem Code falsch aussiehtVerwenden von Rekursion zum Lösen eines Maze in Java

public class RatRoute { 
private static String[] enc; 
private static int count; 
private static int[] r; 
private static int[] c; 

// Test the program 
public static void main(String[] args) { 
    String[] test = { 
      ".R...", 
      "..X..", 
      "....X", 
      "X.X.X", 
      "...C."}; 
    int num1 = numRoutes(test); 
    System.out.println(num1); 
} 

// Set variables, and call recursive function 
public static int numRoutes(String[] enc) { 
    RatRoute.enc = enc;  
    r = findR(enc); 
    c = findC(enc); 
    recursiveHelper(r[0], r[1]); 
    return count; 
} 

// Recursive 
public static void recursiveHelper(int x, int y) { 

    /*System.out.println(); 
    System.out.println(); 
    for (int k = 0; k < enc.length; k++) { 
     System.out.println(enc[k]); 
    }*/ 

    if(isBlock(x,y)) { 
     return; 
    } else if (isBigger(x,y)) { 
     return; 
    } else if (isCheese(x, y)) { 
     count++; 
     //System.out.println("Found the Cheese! Path number: " + count); 
     //System.out.println(); 
     return; 
    } 

    enc[x] = currentPath(x,y);  
    recursiveHelper(x + 1, y); 
    recursiveHelper(x, y + 1); 
    recursiveHelper(x, y - 1); 
    recursiveHelper(x - 1, y); 
    enc[x] = returnPath(x,y); 

} 

// Change the most recently traveled coordinates into a block 
public static String currentPath(int x, int y) { 
    char[] Chars = enc[x].toCharArray(); 
    Chars[y] = 'X'; 
    String newString = String.valueOf(Chars); 
    return newString;  
} 

// Turn path already traveled from blocks back into a usable path to travel (undo the currentPath method) 
public static String returnPath(int x, int y) { 
    char[] Chars = enc[x].toCharArray(); 
    Chars[y] = '.'; 
    String newString = String.valueOf(Chars); 
    return newString;  
} 

// Check if the next movement is into the cheese 
public static boolean isCheese(int x, int y) { 
    if (enc[x].charAt(y) == 'C') { 
     return true; 
    } else { 
     return false; 
    } 
} 

// Check if the next movement is into a block, or outside the given array 
public static boolean isBlock(int x, int y) { 
    if (x == -1 || y == -1 
      || x >= enc.length || y >= enc[x].length()) { 
     return true; 
    } else if (enc[x].charAt(y) == 'X') { 
     //System.out.println(x + "," + y); 
     return true; 
    } else { 
     return false; 
    } 
} 

// See if the distance between the rat and the cheese has gotten larger or smaller 
public static boolean isBigger(int x, int y) { 
    double rx = r[0]; double ry = r[1]; 
    double cx = c[0]; double cy = c[1]; 

    double originalDist = Math.sqrt(Math.pow(rx-cx, 2) + Math.pow(ry-cy, 2)); 
    double newDist = Math.sqrt(Math.pow(x-cx, 2) + Math.pow(y-cy, 2)); 

    //System.out.println("Orginal Distance: " + originalDist); 
    //System.out.println("New Distance: " + newDist); 

    if (newDist > originalDist) { 
     return true; 
    } else { 
     return false; 
    } 
} 

// Find the variables for the original position of the rat 
public static int[] findR(String[] enc) { 
    for (int i = 0; i < enc.length; i++) { 
     for (int j = 0; j < enc[i].length(); j++) { 
      if (enc[i].charAt(j) == 'R') { 
       int[] coordinates = {i, j}; 
       //System.out.println(coordinates[0] + "," + coordinates[1]); 
       return coordinates;     
      } else { 

      } 
     } 
    } 
    int[] other = {-1, -1}; 
    return other; 
} 

// Find the variables for the original position of the rat 
public static int[] findC(String[] enc) { 
    for (int i = 0; i < enc.length; i++) { 
     for (int j = 0; j < enc[i].length(); j++) { 
      if (enc[i].charAt(j) == 'C') { 
       int[] coordinates = {i, j}; 
       //System.out.println(coordinates[0] + "," + coordinates[1]); 
       return coordinates;     
      } else { 

      } 
     } 
    } 
    int[] other = {-1, -1}; 
    return other; 
} 

}

+0

Die Antwort auf das bestimmte Beispiel im Code wäre 3, wenn das hilft. – Steve

Antwort

0

die von einer nützlichen Beobachtung beginnen lassen:

[...] ohne jemals den (euklidischen) Abstand zwischen sich und den Käse an irgendeiner Stelle seines Weges zu erhöhen.

Grundsätzlich bedeutet es, dass, wann immer die Ratte näher an den Käse kommt, sie niemals in eine weiter entfernte Position zurückkehrt.

ist so sagen lassen die Ratte x Koordinate 3 und der Käse x Koordinate 5 die Ratte kann nicht „nach links“ (das heißt x = 2), weil diese es würde dazu führen, weiter zu sein als vor dem Käse bilden.

Aus diesem Grund ist eine gute Möglichkeit, das Problem einfach zu finden, die Richtungen, die die Ratte gehen kann. In Ihrem Beispiel ist die Ratte oben links vom Käse, so dass sie sich nur nach unten oder nach rechts bewegen kann, weil sie sonst weiter vom Käse entfernt wäre. Wenn die Ratte x mit dem Käse x übereinstimmt, kann sie sich nicht mehr rechts oder links bewegen, dasselbe gilt für die y.

mit Ihrem Code, wenn:

r[0] - c[0] = 0 // the rat cannot move on the x any more. 
r[1] - c[1] = 0 // the rat cannot move on the y any more. 

Wenn

r[0] - c[0] == 0 && r[1] - c[1] == 0 

Die Ratte den Käse erreicht! In diesem Fall können wir den Zähler erhöhen, weil eine erfolgreiche Route gefunden wurde.

Jetzt lassen Sie uns dies mit Rekursion in die Praxis umsetzen. Aus dem Code, den Sie geschrieben, beginnen wir mit einem bestimmten c (mit findC(enc) gefunden) und einem gegebenen r

die rekursive Methode wie folgt aussehen würde also (mit findR(enc) gefunden):

private void findRoutesFrom(int[] r) { 
    // what directions can the rat go? 
    // if the cheese is on the right of the mouse, xDirection 
    // would be +1. 
    int xDirection = (int) Math.signum(c[0] - r[0]); 
    // if the cheese is below of the mouse, yDirection 
    // would be +1. 
    int yDirection = (int) Math.signum(c[1] - r[1]); 

    // Now, if xDirection is != 0 the rat can attempt to move 
    // in that direction, checking if there's not a block 
    if(xDirection != 0 && !isBlock(r[0] + xDirection, r[1])) { 
     // if it can move in that direction, then use recursion to 
     // find all the possible paths form the new position 
     findRoutesFrom(new int[]{r[0] + xDirection, r[1]}); 
    } 

    // same goes for yDirection 
    if(yDirection != 0 && !isBlock(r[0], r[1] + yDirection)) { 
     findRoutesFrom(new int[]{r[0], r[1] + yDirection}); 
    } 

    // if the rat reaches the cheese, increase the successful 
    // paths counter 
    if(xDirection == 0 && yDirection == 0) { 
     count++; 
    } 
} 

Das ist es! Wegen der ecueläischen Abstandsbeschränkung ist es ausreichend zu überprüfen, ob die Richtungen != 0 sind, denn wenn das falsch ist, kann sich die Ratte nicht mehr in diese Richtung bewegen.