我是这个网站的新手,如果我的问题有任何问题,请纠正我。我一直收到这个错误,我不完全确定我的程序出了什么问题:
线程“main”中的异常java.lang.IllegalArgumentException:参数N必须为正
at StdRandom.uniform(StdRandom.java:119)
at Maze.chooseRandomlyFrom(Maze.java:52)
at Maze.expandMaze(Maze.java:136)
at Maze.main(Maze.java:193)**
我在IDE(eclipse)中运行了JUnit测试但是我无法追踪错误的来源。非常感谢任何帮助或指导,并感谢您花时间查看代码。这是我正在使用的。我尽可能清楚地为每种方法添加了评论。
public class Maze {
public static final int EAST = 1;
public static final int NORTH = 0;
public static final int[][] OFFSETS = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
public static final int SOUTH = 2;
public static final int WEST = 3;
//Purpose: Modifies passage to contain a one-way passage from location a to location
//b. Assumes these two locations (arrays of two numbers) are adjacent.
//Parameters: boolean[][][] passages, int[] a, int[] b
//Return: N/A
public static void addPassage(boolean[][][] passages, int[] a, int[] b)
{
int ax = a[0];
int ay = a[1];
int bx = b[0];
int by = b[1];
if (by == ay + 1) {
passages[ax][ay][0] = true;
} else if (bx == ax + 1) {
passages[ax][ay][1] = true;
} else if (by == ay - 1) {
passages[ax][ay][2] = true;
} else {
passages[ax][ay][3] = true;
}
}
//Purpose: Gets array of pairs containing start and all locations in the list.
//Parameters: int[] start, int[][] list
//Return: Returns a new array of pairs containing start followed by all of the locations in list.
public static int[][] addToFront(int[] start, int[][] list)
{
int[][] path = new int[list.length + 1][];
path[0] = start;
for (int i = 1; i < path.length; i++) {
path[i] = list[(i - 1)];
}
return path;
}
//Purpose: Gets random one from the first element of the list
//Parameters: int[][] list, int n
//Return: Returns a random one of the first n elements of list.
public static int[] chooseRandomlyFrom(int[][] list, int n)
{
return list[StdRandom.uniform(n)];
}
//Purpose: Gets pair and compares to first number as one of the first n element
//Parameters: int[] pair, int[][] list, int n
//Return: Returns true if pair, assumed to be an array of two numbers, has the same
//numbers as one of the first n elements of list.
public static boolean contains(int[] pair, int[][] list, int n)
{
for (int i = 0; i < n; i++) {
if ((pair[0] == list[i][0]) && (pair[1] == list[i][1])) {
return true;
}
}
return false;
}
//Purpose: Will draw the maze
//Parameters: boolean[][][] passages
//Return: N/A
public static void drawMaze(boolean[][][] passages)
{
StdDraw.clear(StdDraw.PINK);
StdDraw.setPenColor(StdDraw.WHITE);
int width = passages.length;
StdDraw.setPenRadius(0.75 / width);
// Draw passages
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
if (passages[x][y][NORTH] || (y + 1 < width && passages[x][y + 1][SOUTH])) {
StdDraw.line(x, y, x, y + 1);
}
if (passages[x][y][EAST] || (x + 1 < width && passages[x + 1][y][WEST])) {
StdDraw.line(x, y, x + 1, y);
}
}
}
// Draw entrance and exit
StdDraw.line(0, 0, -1, 0);
StdDraw.line(width - 1, width - 1, width, width - 1);
StdDraw.show(0);
}
//Purpose: Will draw the maze solution
//Parameters: int[][] path, int width
//Return: N/A
public static void drawSolution(int[][] path, int width)
{
StdDraw.setPenColor(); // Black by default
StdDraw.setPenRadius();
StdDraw.line(0, 0, -1, 0);
StdDraw.line(width - 1, width - 1, width, width - 1);
for (int i = 0; i < path.length - 1; i++) {
StdDraw.line(path[i][0], path[i][1], path[i + 1][0], path[i + 1][1]);
}
StdDraw.show(0);
}
//Purpose: Checks if here's neighbor in direction (called there) is in unexplored. If so, adds a passage from here
//to there and returns there. If not,returns null.
//Parameters: boolean[][][] passages, int[][] unexplored, int n, int[] here, int direction otherwise.
public static int[] expandLocation(boolean[][][] passages, int[][] unexplored, int n, int[] here, int direction)
{
int[] there = new int[2];
here[0] += OFFSETS[direction][0];
here[1] += OFFSETS[direction][1];
if (contains(there, unexplored, n))
{
addPassage(passages, here, there);
return there;
}
return null;
}
//Purpose: Chooses "here" to be either lastExploredLocation (if it is not null) or a random location in
//frontier. If possible, adds a passage from "here" to a location "there" in unexplored, then moves "there" from unexplored to
//frontier. If not, moves "here" from frontier to done.
//Parameters: boolean[][][] passages, int[][] done, int[][] frontier, int[][] unexplored, int[] counts, int[] lastExploredLocation
//Return: N/A
public static int[] expandMaze(boolean[][][] passages, int[][] done, int[][] frontier, int[][] unexplored, int[] counts, int[] lastExploredLocation)
{
int[] here;
if (lastExploredLocation == null) {
here = chooseRandomlyFrom(frontier, counts[1]);
} else {
here = lastExploredLocation;
}
int direction = StdRandom.uniform(4);
for (int i = 0; i < 4; i++)
{
int[] there = expandLocation(passages, unexplored, counts[2], here, direction);
if (there != null)
{
frontier[counts[1]] = there;
counts[1] += 1;
remove(there, unexplored, counts[2]);
counts[2] -= 1;
return there;
}
direction = (direction + 1) % 4;
}
done[counts[0]] = here;
counts[0] += 1;
remove(here, frontier, counts[1]);
counts[1] -= 1;
return null;
}
//Purpose: Draws then solves maze
//Parameters: String[] args
//Return: N/A
public static void main(String[] args)
{
int width = 20;
StdDraw.setXscale(-0.5, width - 0.5);
StdDraw.setYscale(-0.5, width - 0.5);
StdDraw.show(0);
boolean[][][] passages = new boolean[width][width][4];
// Initially, no locations are done
int[][] done = new int[width * width][];
// The frontier only contains {0, 0}
int[][] frontier = new int[width * width][];
frontier[0] = new int[] { 0, 0 };
// All other locations are in unexplored
int[][] unexplored = new int[width * width][];
// Number of nodes done, on the frontier, and unexplored
int[] counts = { 0, 1, width * width - 1 };
int i = 0;
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
if (x != 0 || y != 0) {
unexplored[i] = new int[] { x, y };
i++;
}
}
}
// As long as there are unexplored locations, expand the maze
int[] lastExploredLocation = null;
while (counts[2] > 0) {
lastExploredLocation = expandMaze(passages, done, frontier, unexplored, counts, lastExploredLocation);
drawMaze(passages);
StdDraw.show(25);
}
// Solve the maze
int[][] solution = solve(passages, new int[] { 0, 0 }, new int[] { width - 1, width - 1 });
drawSolution(solution, width);
}
//Purpose: Modifies list so that pair is replaced with the (n - 1)th element of list. Assumes pair is an
//array of two numbers that appears somewhere in list. Thus, when this method is done, the first n - 1 element of list are
//the same as the first n elements of the old version, but with pair removed and with the order of elements potentially different.
//Parameters: int[] pair, int[][] list, int n
//Return: N/A
public static void remove(int[] pair, int[][] list, int n)
{
for (int i = 0; i < n; i++) {
if ((pair[0] == list[i][0]) && (pair[1] == list[i][1]))
{
list[i] = list[(n - 1)];
return;
}
}
}
//Purpose: Gets a return path from start to finish
//Parameters: boolean[][][] passages, int[] start, int[] goal
//Return: Returns a path (sequence of locations) leading from start to goal in passages or null if there is no such path.
public static int[][] solve(boolean[][][] passages, int[] start, int[] goal) {
if ((start[0] == goal[0]) && (start[1] == goal[1])) {
return new int[][] { goal };
}
for (int d = 0; d < 4; d++) {
if (passages[start[0]][start[1]][d] != false)
{
int[] next = { start[0] + OFFSETS[d][0], start[1] + OFFSETS[d][1] };
int[][] restOfPath = solve(passages, next, goal);
if (restOfPath != null) {
return addToFront(start, restOfPath);
}
}
}
return null;
}
}
答案 0 :(得分:0)
当您将参数'n'传递给。时 Maze.chooseRandomlyFrom(Maze.java:52)中的StdRandom.uniform()你传递的参数是否定的。根据错误消息,参数必须为正。这可能是因为在expandMaze期间,您将计数[1]分配为比其当前值小1(计数[1] - = 1;),这最终将导致负数。似乎只要计数[2]&gt;就会反复调用该方法。 0,在某些情况下必须是足够迭代的情况,例如计数[1]变为负数。
也许在调用此StdRandom.uniform()方法之前,您应该采用计数[1]的绝对值来确保它始终为正。 Math.abs(计数[1])应该可以解决问题。