我正在编写一个同时使用Stack和Queue解决迷宫的JAVA程序。我快完成了。但是我的代码崩溃,数组索引超出范围。很明显它从我的迷宫中消失了。
我已经制作了一种方法,可以检查索引是否在范围之内,但似乎无法正常工作,仍然给我一个错误。
也许解决方案正盯着我,但我似乎无法找出问题所在 抱歉,我的业余代码练习...我正在学习。 如果有人可以帮助我,我将不胜感激。 谢谢。
/*
The input is a simple text file:
And this is what the output should look like.
Please enter the input file name (.txt only):
sample1.txt
Processing sample1.txt...
The initial maze is:
#######
#...#S#
#F#...#
#######
The path found using a stack is:
#######
#***#S#
#F#***#
#######
Path from start to finish: (1, 5) (2, 5) (2, 4) (2, 3) (1, 3) (1, 2) (1, 1) (2, 1)
The path found using a queue is:
#######
#***#S#
#F#***#
#######
Path from start to finish: (1, 5) (2, 5) (2, 4) (2, 3) (1, 3) (1, 2) (1, 1) (2, 1)
Processing terminated normally.
*/
// this'll test the type of square
enum SquareType{
START,
FINISH,
PATH,
WALL,
}
// This will represent one location in the maze, it will stores information about
// that location, and update whether it is a path or a wall and whether it is
// a start/origin or finish/destination.
public class Position {
// instance variables
// these are the coordinates
private int row;
private int col;
private SquareType type;
private boolean visited;
private Position prev; // reference to the previous position on the path
// getters and setters
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public SquareType getType() {
return type;
}
public void setType(SquareType type) {
this.type = type;
}
public boolean isVisited() {
return visited;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public Position getPrev() {
return prev;
}
public void setPrev(Position prev) {
this.prev = prev;
}
private static final String wall = "#";
private static final String start = "S";
private static final String finish = "F";
private static final String path = ".";
// reference to the previous position
// Constructor accepts row, col and type
public Position(int row, int col, SquareType type) {
this.row = row;
this.col = col;
this.type = type;
// the constructor should set the other fields to default values
this.visited = false;
this.prev = null;
}
// checks and indicates whether the position has been visited
// displays the maze or lists the path
public String pathString() {
String myString = null;
if (type == SquareType.WALL) {
myString = wall;
}
if (type == SquareType.FINISH) {
myString = finish;
}
if (type == SquareType.PATH) {
myString = path;
}
if (type == SquareType.START) {
myString = start;
}
return myString;
}
public String printCoordinates() {
String str = "";
str += " (";
str += row;
str += ", ";
str += col;
str += ") ";
return str;
}
}
// This class will store Positions,
// Queue will be implemented using Linked List
// this will be a circular linked list with end pointer
public class Queue {
public class Node{
public Position item;
public Node next;
public Node(Position item, Node next) {
this.item = item;
this.next = next;
}
}
private Node last; // a pointer to the last node in the queue
// Constructor
public Queue() {
last = null;
}
// checks if my list is empty
public boolean isEmpty() {
return last == null;
}
// inserts at the end of the list
public void enqueue(Position item) {
// last nodes's next pointer will point at new node
// then point the new node to the first node
// make the last point at new node
if (!isEmpty()) {
last.next = new Node(item, last.next);
last = last.next;
} else {
// if it is the only node then make it point to itself
last = new Node(item, null);
last.next = last;
}
}
// remove the front item and return it
public Position dequeue() {
// the first node has to be removed
// i.e. last's next node
// and last points at the end
Position pos = null;
if (isEmpty()) {
System.out.println("Queue list is empty");
} else {
pos = last.next.item;
// if there's more than one node
if (last.next != last) {
last.next = last.next.next;
}else {
// if there's only 1 node, delete it
last = null;
}
}
return pos;
}
// returns the front item
// i.e. the last item's next item
public Position front() {
Position result = null;
if (isEmpty()) {
System.out.println("Queue list is empty");
} else {
result = last.next.item;
}
return result;
}
}
// This class will store Positions
// Stack will be implemented using an array
public class Stack {
private int top; // index of the top item (if any)
private Position[] stack;
// Constructor
public Stack(int size){
stack = new Position[size];
top = -1;
}
// Pushes on top of the list
public void push(Position data) {
// check if the stack is full
if (isFull()) {
System.out.println("Stack is full");
}else{
top++; // increment top first
stack[top] = data;
}
}
// remove top item from stack and return it
public Position pop() {
Position topItem = null;
if (isEmpty()) {
System.out.println("Stack is empty");
} else {
// store the top item of the stack in topItem
topItem = stack[top];
stack[top] = null;
top--;
}
return topItem;
}
// returns the top item of the stack
public Position peek() {
Position result = null;
if (!isEmpty()) {
result = stack[top];
} else {
System.out.println("ERROR: Stack is empty");
}
return result;
}
// returns the size
public int size() {
return top + 1;
}
// checks if my stack is empty
// if my top index is -1 then stack is empty
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == stack.length - 1;
}
}
Position,Stack和Queue类很好。问题出在迷宫课上。
import java.io.*;
import java.util.Scanner;
public class Maze {
// 2D array of Positions
private Position[][] posArray;
private int row;
private int col;
private Position start;
private Position finish;
// private static final String wall = "#";
// private static final String start = "S";
// private static final String finish = "F";
// private static final String path = ".";
//Maze constructor
// read input file, create 2D array of appropriate size
// then fill the array
public Maze(String inputfile) {
FileReader fileReaderIn;
BufferedReader fileIn;
String inputLine;
try {
fileReaderIn = new FileReader(inputfile);
fileIn = new BufferedReader(fileReaderIn);
String stringArray; // array to store words
inputLine = fileIn.readLine();
System.out.println("Processing line: " + inputfile);
System.out.println();
String size[];
while (inputLine != null) {
size = inputLine.split(" "); // splits the first line by space.
//size[0] is the row
// size[1] is the col
row = Integer.parseInt(size[0]);
col = Integer.parseInt(size[1]);
posArray = new Position[row][col]; // create an array of size row x col
// we have created the array reading the first line
// now we have to read the next lines
// and fill the array with what we have read.
// read the next line till the number of rows
for (int i = 0; i < row; i++) {
//inputLine = fileIn.readLine();
String nextLine = fileIn.readLine(); // keep reading the next line
String[] charArray = nextLine.split("");
for (int j = 0; j < col; j++) {
SquareType type = null;
if (charArray[j] .equals("#")) { // checking if the character read is equal to #
type = SquareType.WALL;
} else if (charArray[j] .equals( ".")) { // checking if the character read is equal to .
type = SquareType.PATH;
}else if (charArray[j]. equals("F")) { // checking if the character read is equal to F
type = SquareType.FINISH;
finish=new Position(i,j,SquareType.FINISH); // save Finish position when found, don't need the search method
}else if (charArray[j].equals("S")) { // checking if the character read is equal to S
type = SquareType.START;
start= new Position(i,j,SquareType.START); // saves the start position when found, don't need the search method
}
posArray[i][j] = new Position(i, j,type ); // creating our position type and filling the array
}
// now you have to separete the string line into characters
// and insert them into columns.
}
// read the next line and then store it in a string
// separate the string into characters then put those characters in the array
inputLine = fileIn.readLine(); // might not need this. you already have a loop for row
}
fileIn.close();
//stackPath(start, finish, posArray);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
// This method searches using Stack
// returns true if the search is successful
public void stackSearch() {
//Boolean result = false;
Position current; // tracker
// add start position to data structure
Stack myStack = new Stack(row * col); // size of stack
// add start position to stack
myStack.push(start);
// mark start position as visited
start.isVisited();
// while(stack not empty)
while (!myStack.isEmpty()) {
current = myStack.pop(); // curr = remove position from stack
Position neighbour;
if (current.equals(finish)) { // if (current is the finish)
//result = true;
// exit search
break; // maze is solved
}
// for (each neighbour of current that is an unvisited path)
// while !neighbour.isVisited
// if (!posArray[current.getRow() - 1][current.getCol()].equals("#") && !isVisited)
else {
Position up = posArray[current.getRow() - 1][current.getCol()]; // UP
Position down = posArray[current.getRow() + 1][current.getCol()]; // DOWN
Position left = posArray[current.getRow()][current.getCol() - 1]; // LEFT
Position right = posArray[current.getRow()][current.getCol() + 1]; // RIGHT
if (isInMaze(up) && !up.equals("#") && !(up.isVisited())) { // if UP has .
neighbour = up; // UP is neighbour
// neighbour.isVisited();
neighbour.setVisited(true); // set UP to visited
// UP neighbour = current.getRow() - 1][current.getCol()
myStack.push(neighbour); // add neighbour to stack
// prev = current;
neighbour.setPrev(current); // we need to keep track of the previous node
}
if (isInMaze(down) && !down.equals("#") && !(down.isVisited())) { // if DOWN has .
neighbour = down; // DOWN is neighbour
neighbour.setVisited(true); // set DOWN to visited
myStack.push(neighbour); // add neighbour to stack
neighbour.setPrev(current); // we need to keep track of the previous node
}
if (isInMaze(left) && !left.equals("#") && !(left.isVisited())) { // if LEFT has .
neighbour = left; // LEFT is neighbour
neighbour.setVisited(true); // set LEFT to visited
myStack.push(neighbour);
neighbour.setPrev(current); // we need to keep track of the previous node
}
if (isInMaze(right) && !right.equals("#") && !right.isVisited()) { // if RIGHT has .
neighbour = right;
neighbour.setVisited(true); // set RIGHT to visited
myStack.push(neighbour);
neighbour.setPrev(current); // we need to keep track of the previous node
}
}
//result = true;
}
printMaze();
//return result;
}
// This method searches using Queue
// returns true if the search is successful
public void queueSearch() {
//Boolean result = false;
Position current = null; // tracker
Position neighbour = null;
// add start position to data structure
Queue myQueue = new Queue();
// add start position to queue
myQueue.enqueue(start);
// mark start position as visited
start.isVisited();
// while(stack not empty)
while (!myQueue.isEmpty()) {
current = myQueue.dequeue(); // removes and returns the first node
//neighbour.setPrev(null);
if (current.equals(finish)) { // if (current is the finish)
//result = true;
// exit search
break; // maze is solved
}
// for (each neighbour of current that is an unvisited path)
// while !neighbour.isVisited
// if (!posArray[current.getRow() - 1][current.getCol()].equals("#") && !isVisited)
else {
Position up = posArray[current.getRow() - 1][current.getCol()]; // UP
Position down = posArray[current.getRow() + 1][current.getCol()]; // DOWN
Position left = posArray[current.getRow()][current.getCol() - 1]; // LEFT
Position right = posArray[current.getRow()][current.getCol() + 1]; // RIGHT
if (isInMaze(up) && !up.equals("#") && !(up.isVisited())) { // if UP has .
neighbour = up; // UP is neighbour
neighbour.setVisited(true); // set UP to visited
myQueue.enqueue(neighbour); // add neighbour to Queue
// prev = current;
neighbour.setPrev(current); // we need to keep track of the previous node
}
if (isInMaze(down) && !down.equals("#") && !(down.isVisited())) { // if DOWN has .
neighbour = down; // DOWN is neighbour
neighbour.setVisited(true); // set DOWN to visited
myQueue.enqueue(neighbour); // add neighbour to Queue
neighbour.setPrev(current); // we need to keep track of the previous node
}
if (isInMaze(left) && !left.equals("#") && !(left.isVisited())) { // if LEFT has .
neighbour = left; // LEFT is neighbour
neighbour.setVisited(true); // set LEFT to visited
myQueue.enqueue(neighbour); // add neighbour to Queue
neighbour.setPrev(current); // we need to keep track of the previous node
}
if (isInMaze(right) && !right.equals("#") && !(right.isVisited())) { // if RIGHT has .
neighbour = right;
neighbour.setVisited(true); // set RIGHT to visited
myQueue.enqueue(neighbour); // add neighbour to Queue
neighbour.setPrev(current); // we need to keep track of the previous node
}
// mark here if VISITED
// I have the coordinates for Position and I can set the type to *
// neighbour.setMarked() or current as visited
// mark that position
// mark(neighbour.getRow(), neighbour.getCol(), "*");
// set neighbour to marked, return a boolean with that position
// then in the print statement check which ones are marked
// print the ones that are marked with *
// i already marked the visited ones as true
}
//result = true;
}
printMaze();
// return result;
}
//true if cell is within maze
public boolean isInMaze(int i, int j) {
if (i >= 0 && i<this.row && j>= 0 && j<this.col) {
return true;
}
else {
return false;
}
}
//true if cell is within maze
public boolean isInMaze(Position pos) {
return isInMaze(pos.getRow(), pos.getCol());
}
// print the maze
public void printMaze() {
for (int i=0; i<row; i++) {
for (int j=0; j<col; j++) {
System.out.print(posArray[i][j].pathString());
//System.out.print(' ');
}
System.out.println();
}
}
// clear all visited cells
// resetMaze() : reset all Positions in the maze to unvisited
public void resetMaze() {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
posArray[i][j].setVisited(false); // clear visited to not visited
}
}
}
// marks the visited position to *
public void mark(int i, int j, SquareType type) {
Position temp = posArray[i][j];
temp.setType(type);
}
// public Position[][] array(int i, int j, Position[][] posArray) { // keep track of positions that are .
// Position[][] dot = new Position[1][4];
//
// if (!posArray[i - 1][j].equals("#")) {// up}
// dot[0][0] = posArray[i - 1][j];
// }
// if (!posArray[i + 1][j].equals("#")) {
// dot[0][1] = posArray[i+1][j];
// } // down
//
// if (!posArray[i][j - 1].equals("#")) {
// dot[0][2] = posArray[i][j - 1];
// }; // left
// if (!posArray[i][j + 1].equals("#")) {
// ; // right}
// dot[0][3] = posArray[i][j + 1];
// }
// return dot;
// }
}