万金流
以码会友。 吾Q:578751655。 水平有限,轻喷,谢!

题:

二维数组表示迷宫(格子组成),0不能走,1能走。求走出路径。

指导思想:

一步步尝试出所有可能,输出成功结果。

尝试过程保存在栈里,一旦走出,栈里保存的就是正确路径。

编程思路:

从某个格子开始找:

如果该格子是出口,成功!
某个格子入栈

某个格子上可用,某个格子上开始找
某个格子右可用,某个格子右开始找
某个格子下可用,某个格子下开始找
某个格子左可用,某个格子左开始找

某个格子出栈

编程:

1、先准备数组,并测试:

public class App
{
    static int[][] a;

    public static void main(String[] args) throws Exception
    {
        a = getArray();
        showArray();
    }

    public static int[][] getArray()
    {
        int[][] x =
        {
                { 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1 },
                { 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1 },
                { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
                { 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
                { 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1 },
                { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
        return x;
    }

    public static void showArray()
    {
        for (int i = 0; i < a.length; i++)
        {
            for (int j = 0; j < a[i].length; j++)
            {
                System.out.print(a[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

测试结果:

 

 目测有正确解,通过。

2、写一个简单的栈,用于保存走过的路径:

public class MyStack
{
    public static int[][] n = new int[150][2];
    public static int p = 150;

    public static void push(int x, int y)
    {
        p--;
        n[p][0] = x;
        n[p][1] = y;
    }

    public static int[] pop()
    {
        int[] x = new int[2];
        if (p == 150)//栈空
        {
            x[0] = -1;
            x[1] = -1;
        }
        else
        {
            x[0] = n[p][0];
            x[1] = n[p][1];
            p++;
        }
        return x;
    }
}

3、按之前的思路,搭好“走迷宫”方法的架子

 //从(x,y)位置开始走迷宫
    public static void goMiGong(int x,int y)
    {
        //如果这个格子是出口,则程序结束
        if(x==7&&y==12)
        {
            //当前格子设置为2
            //输出数组
            //退出程序
        }
        else
        {
            //当前格子设置为2,入栈
            //*按上、右、下、左顺序依次走其他格子
            //出栈(且还原为1)(栈空则无解)
        }
    }

4、回头阅读上面的程序,打星号的部分稍微有一点复杂,希望有一个方法,辅助判断某个格子是否可以走。代码如下: 

public static boolean nengZou(int x,int y)
    {
        boolean b=false;
        if(x>=0&&y>=0)
        {
            if(a[x][y]==1)
            {
                b=true;
            }
        }
        return b;
    }

5、一切准备完毕,用上面的东西拼装起整个程序。调试后代码如下:

主程序(app.java)

public class App
{
    static int[][] a;
    // 存放出栈元素的位置,如(3,2)
    static int[] p = new int[2];

    public static void main(String[] args) throws Exception
    {
        a = getArray();
        System.out.println("原始迷宫:");
        showArray();
        System.out.println("-----------------------------------");
        goMiGong(0, 0);
    }

    public static int[][] getArray()
    {
        int[][] x =
        {
                { 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1 },
                { 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1 },
                { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
                { 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
                { 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1 },
                { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
        return x;
    }

    public static void showArray()
    {
        for (int i = 0; i < a.length; i++)
        {
            for (int j = 0; j < a[i].length; j++)
            {
                System.out.print(a[i][j] + "\t");
            }
            System.out.println();
        }
    }

    // 从(x,y)位置开始走迷宫
    public static void goMiGong(int x, int y)
    {
        // 如果这个格子是出口,则程序结束
        if (x == 7 && y == 12)
        {
            // 当前格子设置为2
            a[x][y] = 2;
            // 输出数组
            System.out.println("迷宫有解:");
            showArray();
            // 退出程序
            System.exit(0);
        }
        else
        {
            // 当前格子设置为2,入栈
            a[x][y] = 2;
            MyStack.push(x, y);
            // 按上、右、下、左顺序依次走其他格子
            if (nengZou(x - 1, y))
            {
                goMiGong(x - 1, y);
            }
            if (nengZou(x, y + 1))
            {
                goMiGong(x, y + 1);
            }
            if (nengZou(x + 1, y))
            {
                goMiGong(x + 1, y);
            }
            if (nengZou(x, y - 1))
            {
                goMiGong(x, y - 1);
            }
            // 出栈(且还原为1)(栈空则无解)
            p = MyStack.pop();
            if (p[0] == -1)
            {
                System.out.println("迷宫无解");
            }
            else
            {
                a[p[0]][p[1]] = 1;
            }
        }
    }

    // 判断(x,y)是否可以走。判断方法:
    // 1、超出数组不能走;2、在栈内(为2)不能走;3、为0不能走
    // 即:都大于等于0,且对应数组值为1,就可以走。
    public static boolean nengZou(int x, int y)
    {
        boolean b = false;
        if (x >= 0 && y >= 0&&x<8&&y<13)
        {
            if (a[x][y] == 1)
            {
                b = true;
            }
        }
        return b;
    }
}

辅助栈(myStack.java)

public class MyStack
{
    public static int[][] n = new int[150][2];
    public static int p = 150;

    public static void push(int x, int y)
    {
        p--;
        n[p][0] = x;
        n[p][1] = y;
    }

    public static int[] pop()
    {
        int[] x = new int[2];
        if (p == 150)//栈空
        {
            x[0] = -1;
            x[1] = -1;
        }
        else
        {
            x[0] = n[p][0];
            x[1] = n[p][1];
            p++;
        }
        return x;
    }
}

程序运行结果:

 

 人为修改最后一行第一个元素的值为0,发现并未输出正确结果。

请检查程序,修改它,得出正确的程序。

 

 提示:判断“迷宫无解”的条件。什么情况下迷宫无解?当弹出迷宫入口的时候,即可判定无解。

思考:1、在这道题目中,栈是必须的吗?2、看看下面的图,猜猜是什么?

 


纯栈版。思路类似,用栈实现。

位置类:

public class MyPoint
{
    public int x,y;
    public MyPoint()
    {
        
    }
    public MyPoint(int _x,int _y)
    {
        x=_x;
        y=_y;
    }
}

主类:

import java.util.Stack;
//程序中状态说明:
//0、不可通过,原始状态
//1、可通过,原始状态
//2、已入栈,尚未尝试
//3、正在尝试
//4、已尝试,无法通过
public class c1
{
    static int[][] a;
    public static void main(String[] args) throws Exception
    {
        Stack<MyPoint> mystack=new Stack<MyPoint>();
        MyPoint mp,t;
        boolean b=false;
        a = getArray();
        System.out.println("原始迷宫:");
        showArray();
        System.out.println("-----------------------------------");
        mystack.push(new MyPoint(0,0));
        a[0][0]=2;
        while(!mystack.empty())
        {
            b=false;
            //peek方法,获取栈顶值,但不出栈。
            mp=mystack.peek();
            a[mp.x][mp.y]=3;
            if(mp.x==7&&mp.y==12)
            {
                System.out.println("有解");
                b=true;
                showArray();
                break;
            }
            t=new MyPoint(mp.x-1, mp.y);
            if(nengZou1(t))
            {
                b=true;
                mystack.push(t);
                a[t.x][t.y]=2;
            }
            t=new MyPoint(mp.x, mp.y+1);
            if(nengZou1(t))
            {
                b=true;
                mystack.push(t);
                a[t.x][t.y]=2;
            }
            t=new MyPoint(mp.x+1, mp.y);
            if(nengZou1(t))
            {
                b=true;
                mystack.push(t);
                a[t.x][t.y]=2;
            }
            t=new MyPoint(mp.x, mp.y-1);
            if(nengZou1(t))
            {
                b=true;
                mystack.push(t);
                a[t.x][t.y]=2;
            }
            if(!b)
            {
                mystack.pop();
                a[mp.x][mp.y]=4;
            }
        }
        if(!b)
        {
            System.out.println("无解");
        }
    }

    public static int[][] getArray()
    {
        int[][] x =
                {
                        { 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1 },
                        { 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1 },
                        { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
                        { 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
                        { 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1 },
                        { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
        return x;
    }

    public static void showArray()
    {
        for (int i = 0; i < a.length; i++)
        {
            for (int j = 0; j < a[i].length; j++)
            {
                System.out.print(a[i][j] + "\t");
            }
            System.out.println();
        }
    }

    public static boolean nengZou1(MyPoint x)
    {
        boolean b = false;
        if (x.x >= 0 && x.y >= 0&&x.x<8&&x.y<13)
        {
            if (a[x.x][x.y] == 1)
            {
                b = true;
            }
        }
        return b;
    }
}

运行效果(其中3为尝试后的通路,2为尚未尝试的点,4为尝试失败的点)

原始迷宫:
1    1    1    0    1    1    0    0    0    1    1    1    1    
1    0    1    1    1    0    1    1    1    1    0    0    1    
0    0    0    0    1    0    1    0    1    0    1    0    0    
1    1    1    0    1    1    1    0    1    0    1    1    1    
1    0    1    0    0    0    0    1    1    1    0    0    1    
1    0    1    1    1    1    1    1    0    1    1    1    1    
1    0    0    0    0    0    0    0    0    0    0    0    0    
1    1    1    1    1    1    1    1    1    1    1    1    1    
-----------------------------------
有解
3    3    3    0    2    1    0    0    0    1    1    1    1    
4    0    3    3    3    0    3    3    3    2    0    0    1    
0    0    0    0    3    0    3    0    3    0    1    0    0    
3    3    3    0    3    3    3    0    3    0    1    1    1    
3    0    3    0    0    0    0    3    3    2    0    0    1    
3    0    3    3    3    3    3    3    0    1    1    1    1    
3    0    0    0    0    0    0    0    0    0    0    0    0    
3    3    3    3    3    3    3    3    3    3    3    3    3

 

posted on 2020-11-09 23:30  万金流  阅读(341)  评论(0编辑  收藏  举报