algorithms/src/main/java/com/github/kuangcp/strcuture/stackapp/OutOfTheMaze.java
package com.github.kuangcp.strcuture.stackapp;
import lombok.extern.slf4j.Slf4j;
/**
* Created by https://github.com/kuangcp on 17-8-22 下午3:11
* 迷宫,找出路径和最短路路径
* 想要实现和c一样用define定义常量(不是用final定义方法内部常量)的功能就要用接口
* 在接口中定义一个常量,再继承这个接口,就能在类中到处用这个常量了
* path的路径没有变过,哪了出错了?、、、
*/
@Slf4j
public class OutOfTheMaze {
private static int top = -1, count = 0, minSize = 100;
//定义一个普通整型的地图,两个栈
//int [][] map = new int [M+2][N+2]; 不需要指明大小
private static final int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 0, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 1},
{1, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 1, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
//只是说放的是point类型的引用,而不是放对象
private static final Point[] stack = new Point[100];
private static final Point[] path = new Point[100];
static class Point {
int row = 1;//行
int col = 1;//列
int choose = -1;//记录岔路口选择状态
}
public static void main(String[] args) {
for (int k = 0; k < minSize; k++) {
stack[k] = new Point();
path[k] = new Point();
}
int found, choose, i, j;
boolean success = false;
int maxRow = 6;
int maxCol = 6;
char[][] print = new char[maxRow + 2][maxCol + 2];
for (int z = 0; z < maxRow + 2; z++) {
for (int x = 0; x < maxCol + 2; x++) {
print[z][x] = (char) map[z][x];
}
}
// log.info("{}", stack[6].row);
top++;
stack[top].row = 1;
stack[top].col = 1; //起始位置是(1,1)
stack[top].choose = 0;
map[1][1] = -1;
while (top > -1) { //栈不为空就循环
i = stack[top].row;
j = stack[top].col;
choose = stack[top].choose;
if (i == maxRow && j == maxCol) { //走到了终点
success = true;
log.info("the {} way:", ++count);
for (int k = 0; k <= top; k++) {
System.out.printf("(%d,%d) ", stack[k].row, stack[k].col);
}
System.out.println("\n");
if (top + 1 < minSize) { //比较 找到最短路径放入path中
System.arraycopy(stack, 0, path, 0, top + 1);
minSize = top + 1;
}
map[stack[top].row][stack[top].col] = 0; // 把破坏的那个终点恢复
top--;
i = stack[top].row;
j = stack[top].col;
choose = stack[top].choose;
}
found = 0;
while (choose < 4 && found == 0) { //开始选择路径
switch (choose++) {
case 0:
i = stack[top].row - 1;
j = stack[top].col;
break; // 上
case 1:
i = stack[top].row;
j = stack[top].col + 1;
break; // 右
case 2:
i = stack[top].row + 1;
j = stack[top].col;
break; // 下
case 3:
i = stack[top].row;
j = stack[top].col - 1;
break; // 左
}
if (map[i][j] == 0) {
found = 1;
}
}
//System.out.println("top="+top);
if (found == 1) {
stack[top].choose = choose;
top++;
stack[top].row = i;
stack[top].col = j;
stack[top].choose = 0;
map[i][j] = -1; //破坏该位置
} else { //没找到
map[stack[top].row][stack[top].col] = 0;
//恢复当前位置,在while和方向choose变量的作用下就能一步步按原路返回
top--;
}
}
if (success) {
showResult(maxRow, maxCol, print);
} else {
log.warn("这个迷宫无解");
}
}
private static void showResult(int maxRow, int maxCol, char[][] print) {
System.out.printf("最短路径的长度 %d\n\n", minSize);
System.out.print("最短的路径:");
for (int k = 0; k < minSize; k++) {
System.out.printf("(%d,%d) ", path[k].row, path[k].col);
print[path[k].row][path[k].col] = '.';
if ((k + 1) % 8 == 0) {
System.out.println();
}
}
System.out.print("\n迷宫地图:\n");
for (int z = 0; z < maxRow + 2; z++) {
for (int x = 0; x < maxCol + 2; x++) {
System.out.printf(" %c", map[z][x]);
}
System.out.println();
}
System.out.println();
System.out.print("\n最短路径如图:\n");
for (int z = 0; z < maxRow + 2; z++) {
for (int x = 0; x < maxCol + 2; x++) {
System.out.printf(" %c", print[z][x]);
}
System.out.println();
}
}
}