RT
我的代码
import java.io.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
//import java.util.Stack;
import java.lang.String;
import java.util.LinkedList;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;public class MazeCell
{
private int x, y;
    public MazeCell() {
     }
     public MazeCell(int i, int j) 
     {
     x=i;
     y=j;
     }
     public boolean equals(Object o) 
     {
     if (!(o instanceof MazeCell))
     return false;
     MazeCell cell = (MazeCell) o;
return cell.x == x && cell.y == y;
}
public String toString()
{
return x + "," + y;
}
public int getX() 
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
}
class Stack<T>
{
private LinkedList<T> storage = new LinkedList<T>();
/** 入栈 */
    public void push(T v)
    {
     storage.addFirst(v);
     }
/** 出栈,但不删除 */
public T peek() {
return storage.getFirst();
}
/** 出栈 */
public T pop() {
return storage.removeFirst();
}
/** 栈是否为空 */
public boolean empty() {
return storage.isEmpty();
}
/** 打印栈元素 */
public String toString() {
return storage.toString();
}
}
class Maze {
private int rows = 0, cols = 0;// 迷宫的行数与列数
private char[][] store, path;// 迷宫矩阵
private MazeCell currentCell, exitCell = new MazeCell(),
entryCell = new MazeCell();// 当前节点,出口节点,入口节点
private static final char EXIT = '9', ENTRY = '6', VISITED = '3';// 出口标记,入口标记,已经过节点标记
private static final char PASS = '0', WALL = '1';// 通路标记,墙标记
private Stack<MazeCell> mazeStack = new Stack<MazeCell>();// 探路过程所使用栈
private List<MazeCell> currentList = new LinkedList<MazeCell>();// 路经的路线队列
public Maze() {// 构造迷宫
int row = 0, col = 0;
Stack<String> mazeRows = new Stack<String>();
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(isr);
System.out.println("Enter a rectangular maze using the following"+ " characters: \n6-entry\n9-exit\n1-wall\n0-passagen"+"Enter one line at a time; end with Ctrl-d;");
try {
String str = buffer.readLine();
while (str != null) 
{
row++;
cols = str.length();
str = "1" + str + "1";
mazeRows.push(str);
if (str.indexOf(EXIT) != -1) 
{
exitCell.setX(row);
exitCell.setY(str.indexOf(EXIT));
}

if (str.indexOf(ENTRY) != -1)
 {
entryCell.setX(row);
entryCell.setY(str.indexOf(ENTRY));
 }
str = buffer.readLine();
}
} catch (IOException e)
{
e.printStackTrace();
}
rows = row;
store = new char[rows + 2][];
store[0] = new char[cols + 2];
for (; !mazeRows.empty(); row--)
store[row] = (mazeRows.pop()).toCharArray();
store[rows + 1] = new char[cols + 2];
for (col = 0; col <= cols + 1; col++)
{
store[0][col] = WALL;
store[rows + 1][col] = WALL;
}path = new char[rows + 2][];
copyArray(store, path);
}
/** 二维数组复制 */
private void copyArray(char[][] src, char[][] tar)
{
for (int i = 0; i < src.length; i++) 
{
tar[i] = new char[cols + 2];
for (int j = 0; j < src[i].length; j++)
tar[i][j] = src[i][j];
}
}
/** 二维数组输出 */
private void display(PrintStream out, char[][] carray) 
{
for (int row = 0; row <= rows + 1; row++)
out.println(carray[row]);
out.println();
}
/** 将未访问并可通路的节点压入栈 */
private void pushUnvisited(int row, int col)
{
if (store[row][col] == PASS || store[row][col] == EXIT)
mazeStack.push(new MazeCell(row, col));
}
/** 探路过程 */
public void exitMaze(PrintStream out)
{
currentCell = entryCell;
currentList.add(currentCell);
out.println();
while (!currentCell.equals(exitCell)) 
{
int row = currentCell.getX();
int col = currentCell.getY();
display(System.out, store);
if (!currentCell.equals(entryCell))
store[row][col] = VISITED;
pushUnvisited(row - 1, col);
pushUnvisited(row + 1, col);
pushUnvisited(row, col - 1);
pushUnvisited(row, col + 1);
if (mazeStack.empty())
{
display(out, store);
out.println("Failure");
return;

else {
currentCell = mazeStack.pop();
currentList.add(currentCell);
}
}display(out, store);
out.println("Success");
}
/** 得到某一输出路线 */
private void getPath() {
if (currentList.size() <= 0)
return;
MazeCell cell = currentList.get(currentList.size() - 1);
while (cell != currentList.get(0)) {
List<MazeCell> subList = currentList.subList(0, currentList.indexOf(cell));
ListIterator<MazeCell> itr = subList.listIterator();
while (itr.hasNext()) 
{
MazeCell target = itr.next();
if (adjoin(cell, target)) 
{
removeElements(currentList.indexOf(target) + 1, currentList.indexOf(cell));
cell = target;
break;
}
}
}
}
/** 删除队列中由from至to的连续元素 */
private void removeElements(int from, int to) {
int turn = to - from;
while (turn > 0) {
            currentList.remove(from);
turn--;
      }
    }
    /** 判断两个节点是否相邻 */
private boolean adjoin(MazeCell current, MazeCell target)
{
if ((current.getX() == target.getX() + 1 || current.getX() == target.getX() - 1)&& (current.getY() == target.getY()))
return true;
if ((current.getY() == target.getY() + 1 || current.getY() == target.getY() - 1)&& (current.getX() == target.getX()))
return true;
return false;
}
    /** 输出路线 */
public void printPath(PrintStream out) {
getPath();
out.println("Path:");
if (currentList.size() >= 2) {
currentList.remove(currentList.size() - 1);
currentList.remove(0);
}
Iterator<MazeCell> itr = currentList.iterator();
while (itr.hasNext()) {
MazeCell cell = itr.next();
path[cell.getX()][cell.getY()] = VISITED;
}
display(System.out, path);
}
public static void main(String[] args) {
Maze maze = new Maze();
maze.exitMaze(System.out);
maze.printPath(System.out);
}
}

解决方案 »

  1.   

    老鼠走迷宫?看看我以前写的这个:
    import java.io.*;
    import java.util.*;
    /** 老鼠走迷宫程序

    * @author bigbug
    * @version 1.0
    *//** Direction 方向枚举类型,八个方向。从北方NORTH到西北WESTNORTH按顺时针方向排列*/
    enum Direction{
    NORTH,
    EASTNORTH,
    EAST,
    EASTSOUTH,
    SOUTH,
    WESTSOUTH,
    WEST,
    WESTNORTH
    }
    /** Maze 迷宫类:
    *  rows:迷宫的行数。
    *  columns:迷宫的列数。
    *  ma:二维字符型数组,其中'1'表示墙,'0'表示通路。在老鼠走迷宫过程中会留下痕迹,'2'表示只路过一次,'3'表示路过二次。
    *  entranceRow,entranceColumn:分别表示迷宫入口的行、列。
    *  exitRow,exitColumn:分别表示迷宫出口的行、列。
    */
    class Maze{
    int rows,columns;
    char[][] ma;
    int entranceRow=0,entranceColumn=0;
    int exitRow=14,exitColumn=14;

      /** Maze类的构造方法。
      * 其实入口和出口的行、列也应该在构造方法中初始化。
      * 但为了省事,在上面的声明中初始化了。
      * @param r 表示迷宫的行数。
      * @param c 表示迷宫的列数。
      */
      Maze(int r,int c){
       rows=r;
       columns=c;
       ma=new char[rows][columns];
       try{
       //由于2.txt文件的格式,只好用BufferedReader,因为要一行行读出来。
       //FileInputStream()方法会抛出FileNotFoundException异常
       BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("f:/java/2.txt")));
       String s="";
       for(int i=0;i<rows;i++){
       //readLine()方法会抛出一个IOException异常
       s=br.readLine();
       for(int j=0;j<columns;j++){
       ma[i][j]=s.charAt(j);
         }
          }
        }catch(FileNotFoundException e){
       System.out.println("File f:\\java\\2.txt not fount!!");
       }catch(IOException ie){
       ie.printStackTrace();
       }
        
      }//Maze()  
      /**打印出迷宫示意图,▇表示墙,□表示通路,m表示只通过一次,p表示通过了两次及以上。*/
      void printMaze(){
       for(int i=0;i<rows;i++){
       for(int j=0;j<columns;j++){
       if(ma[i][j]=='1'){
       System.out.print("▇");
       }else if(ma[i][j]=='0'){
       System.out.print("□");
       }else if(ma[i][j]=='2'){
       System.out.print("m ");
       }else{
       System.out.print("p ");
       }
       }
       System.out.println("");
      
       }
      }
    }
    /** Mouse类
     * posRow,posColumn表示老鼠在迷宫的当前位置,即所处的行,列
     * direction 老鼠要向那个方向走
     * maze 迷宫。
     * trace 一个堆栈,存放老鼠走过的地方(迷宫中的行、列),以便走不通时,能退回到上一步路过的位置。
     * passable 一个boolean型数组,用以标记迷宫中的某方格mouse是否能走.没有这个数组,程序可能会有死循环。
     * 如pasable[i][j]的值为false 表示迷宫中行为i,列为j的方格老鼠不可以走。要么这个格是墙,要么曾经走过。
    */
    public class Mouse{
    int posRow,posColumn;
    Direction direction;
    Maze maze;
    Stack trace;
    boolean[][] passable;
    /**Mouse 类的构造方法*/
    Mouse(int posRow,int posColumn,Direction d){
    this.posRow=posRow;
    this.posColumn=posColumn;
    direction=d;
    maze=new Maze(15,15);
    trace=new Stack();
    passable=new boolean[maze.rows][maze.columns];
    //下面的循环是对passable数组进行初始化,对照迷宫的ma进行,对墙打false标记,通路打true标记
    for(int i=0;i<maze.rows;i++){
    for(int j=0;j<maze.columns;j++){
    if(maze.ma[i][j]=='1'){
    passable[i][j]=false;
    }else{
    passable[i][j]=true;
    }
    }
    }
    }
    /**探测下一个可以走的位置,并走过去,如果成功返回true,否则返回false*/
    boolean getNextPosition(){
        //增强型for循环,continue,break也可以用在其中。
        //关于枚举类型的应用可以查http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html。
        //这个循环遍历了所有的方向,显然可以优化。可以从当前的方向顺时针转到WESTNORTH。要用到EnumSet类。
         for(Direction d:Direction.values()){
         //判断下一位置是否超出了迷宫的边界
         //对于方向d,老鼠从当前位置朝着d方向走时,行,列的值会变化,变化的值由getRowOffset方法和getColumnOffset方法得到。
         if(posRow+getRowOffset(d)<0||posRow+getRowOffset(d)>=maze.rows||posColumn+getColumnOffset(d)<0||posColumn+getColumnOffset(d)>=maze.columns)
            continue;
         //如果下一位置可以走,就走过去,否则进行下一次循环继续找。
         if(!passable[posRow+getRowOffset(d)][posColumn+getColumnOffset(d)]){
         continue;
         }else{
         posRow+=getRowOffset(d);
         posColumn+=getColumnOffset(d);
         direction=d;
         return true;
         }
         }
         //程序能运行到这里,表示上面的return true;没有被执行过,也就是没有找到一个可以走的位置,返回false;
         return false;
        }
        /** 走迷宫
        */
        boolean throughMaze(){
         trace.push(posRow);         //把入口的行值压入栈
         trace.push(posColumn);      //把入口的列值压入栈
         //把入口时老鼠的方向压入栈,在本程序中这个动作没有必要,但 如果要优化getNextPosition()中的for循环,这个动作就是必需的了。
         trace.push(direction); 
         passable[posRow][posColumn]=false;  //当值位置标记为不可走。
         //当栈不空,且没有到达出口时一直循环。
         //栈空表示老鼠退回到了入口。这时表示这个迷宫没有通路到达出口。
         while(!trace.empty()&&(posRow!=maze.exitRow||posColumn!=maze.exitColumn)){
         if(getNextPosition()){
          trace.push(posRow);
          trace.push(posColumn);
         trace.push(direction);
         passable[posRow][posColumn]=false;
         maze.ma[posRow][posColumn]='3';   //留下足迹,'3'表示路过多次,这是假设,走完迷宫后再做修正。
         }else{  //从当前位置没有找到可以通过的方格时,下面的动作就是退回上一步,以便从那里再找。
          //退回上一步,就是出栈,留意出栈的顺序。
         direction=(Direction)trace.pop();
          posColumn=((Integer)trace.pop()).intValue();
          posRow=((Integer)trace.pop()).intValue();
         }
         }
         //退出while循环之后,栈空表示迷宫没有通路。
         if(trace.empty()){
          return false;
         }else{       //栈非空,有通路,栈中存放的就是老鼠只经过一次的那些位置。
          //一直出栈,直到栈为空。
          while(!trace.empty()){
          int r,c;
          trace.pop(); //方向出栈,下面用不到方向了,数据扔掉,但动作不可少。
          c=((Integer)trace.pop()).intValue();
          r=((Integer)trace.pop()).intValue();
          maze.ma[r][c]='2';  //把行为r,列为c的方格修正为只经过一次。
          }
          return true;
         }
        }
        /**返回老鼠当前方格的行值与d方向的方格的行值偏移量
        * @param d 方向*/
        int getRowOffset(Direction d){
         int offset=2;
         switch(d){
         case NORTH:     offset= -1; break;//从当前方格走到北面的方格,行值应该减1.下面类似。
         case EASTNORTH: offset= -1; break;
         case EAST:      offset= 0; break;
         case EASTSOUTH: offset= 1; break;
         case SOUTH:     offset= 1; break;
         case WESTSOUTH: offset= 1; break;
         case WEST:      offset= 0; break;
         case WESTNORTH: offset= -1;
         }
         return offset;
        }
        /**返回老鼠当前方格的列值与d方向的方格的列值的偏移量*/
        int getColumnOffset(Direction d){
         int offset=2;
         switch(d){
         case NORTH:     offset= 0; break; //从前方格走到北面的方格,列值不变。下面类似。
         case EASTNORTH: offset= 1; break;
         case EAST:      offset= 1; break;
         case EASTSOUTH: offset= 1; break;
         case SOUTH:     offset= 0; break;
         case WESTSOUTH: offset= -1; break;
         case WEST:      offset= -1; break;
         case WESTNORTH: offset= -1;
         }
         return offset;
        }
        public static void main(String[] args){
         Mouse mouse=new Mouse(0,0,Direction.NORTH);
         System.out.println("The maze:");
         mouse.maze.printMaze();  //打印初始状态的迷宫
         /*试图清除dos窗口的屏幕,不成功。可能执行,cmd是打开一个新的dos窗口,所以cls是清除新窗口的屏幕,而不是当前的。
         try{
         Runtime.getRuntime().exec("cmd.exe /k cls");
         }catch(Exception e){
         e.printStackTrace();
         }
         */
         if(mouse.throughMaze()){
         System.out.println("Trace of mouse:");
         mouse.maze.printMaze();  //打印经过老鼠践踏后的迷宫:)
         System.out.println("m---pass by  for once .  p----pass by many times ");
         }else{
         System.out.println("No pass!");
         }
        }
    }
    2.txt内容:
    011111111111111
    101110011100111
    101101110101001
    110101000011101
    110101011011010
    100101011011110
    111011101000011
    110111001110100
    101001011001110
    101111011010001
    100011101011111
    110100101010001
    110101011101101
    111010100101001
    111111111111110