如何解决关于此哈密顿循环问题的NullPointerException
| 以下代码在10x10或8x8棋盘上从位置0 0开始时,为棋盘上的骑士找到了正确的汉密尔顿周期,但在其他任何地方启动时,抛出NullPointerException。 输入应为8
8
0
0
对于从位置0 0开始的8x8棋盘上的汉密尔顿循环,它将运行正确的输出:
1 16 27 22 3 18 29 32
26 23 2 17 28 31 4 19
15 64 25 36 21 50 33 30
24 37 48 61 56 35 20 5
47 14 63 38 49 60 51 34
42 39 44 57 62 55 6 9
13 46 41 54 11 8 59 52
40 43 12 45 58 53 10 7
上
8
8
1
1
我得到:
Exception in thread \"main\" java.lang.NullPointerException
at horseBETA.mover(horseBETA.java:55)
at horseBETA.search(horseBETA.java:130)
at horseBETA.main(horseBETA.java:164)
Java Result: 1
为什么?
import java.util.Scanner;
/**
*
* @author Darwin Martinez
*/
class position{
int x,y;
position() {};
position(int a,int b) { x=a; y=b; }
}
public class horseBETA {
static int number_of_movements = 8;
static int dx[] = {-1,-2,-1,1,2,1};
static int dy[] = {-2,-2};
static int longCycle;
static int N,M,I,J;
static int[][] order;
position solucion[];
static boolean free[][];
static int longitud;
static int dfs_visited[][],stampdfs;
horseBETA(int N,int M,int I,int J) {
longCycle = N*M;
order = new int[N][M];
solucion = new position[longCycle];
free = new boolean [N][M];
dfs_visited = new int[N][M];
for (int i=0;i<N;i++)
for (int j=0;j<M;j++) {
free[i][j] = true;
dfs_visited[i][j] = 0;
}
stampdfs = 0;
position aux=new position(I,J);
int index=(I*N)+J;
solucion[index]=aux;
free[I][J] = false;
longitud = 1;
}
boolean valida(position p) {
return 0<=p.x && p.x<N &&
0<=p.y && p.y<M && free[p.x][p.y];
}
position mover(position p,int i) {
return new position(p.x+dx[i],p.y+dy[i]);
}
boolean es_terminal() {
return longitud == longCycle;
}
boolean is_factible(position p) {
return ((p.x == I+dx[0] && p.y == J+dy[0]) || (p.x == I+dx[1] && p.y == J+dy[1])
|| (p.x == I+dx[2] && p.y == J+dy[2])|| (p.x == I+dx[3] && p.y == J+dy[3])
|| (p.x == I+dx[4] && p.y == J+dy[4])|| (p.x == I+dx[5] && p.y == J+dy[5])
|| (p.x == I+dx[6] && p.y == J+dy[6])|| (p.x == I+dx[7] && p.y == J+dy[7]));
}
boolean prometedor_recurs(position d) {
if (is_factible(d)) return true;
for (int i=0;i<number_of_movements;i++) {
position a = mover(d,i);
if (valida(a) && dfs_visited[a.x][a.y] != stampdfs) {
dfs_visited[a.x][a.y] = stampdfs;
if (prometedor_recurs(a)) return true;
}
}
return false;
}
boolean promising(position d) {
stampdfs++;
return prometedor_recurs(d);
}
void print_solution() {
for (int i=0;i<longCycle;i++)
order[solucion[i].x][solucion[i].y] = i+1;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if(order[i][j]<10)
System.out.print(\" \"+order[i][j]);
else{
if(order[i][j]>=10&&order[i][j]<100)
System.out.print(\" \"+order[i][j]);
else
System.out.print(\" \"+order[i][j]);
}
}System.out.print(\"\\n\");
}
System.exit(0);
}
void insertionSort(position p[],int r[],int n) {
int i,j,aux;
position auxp;
for (i=1; i<n; i++) {
aux=r[i]; auxp = p[i];
for (j=i-1; j>=0 && aux<r[j]; j--) {
r[j+1]=r[j]; p[j+1]=p[j];
}
r[j+1]=aux; p[j+1] = auxp;
}
}
public boolean search() {
if (es_terminal()) {
if (is_factible(solucion[longCycle-1])){
print_solution();
return true;
}
} else {
int nchildren = 0;
position p[]=new position[number_of_movements];
int r[]=new int[number_of_movements];
for (int i=0;i<number_of_movements;i++) {
position a = mover(solucion[longitud-1],i);
if (valida(a)) {
int grado = 0;
for (int j=0;j<number_of_movements;j++)
if (valida(mover(a,j)))
grado++;
p[nchildren] = a;
r[nchildren] = grado;
nchildren++;
}
}
insertionSort(p,r,nchildren);
for (int i=0; i<nchildren; i++) {
solucion[longitud] = p[i]; longitud++;
free[p[i].x][p[i].y] = false;
if (promising(p[i]))
search();
free[p[i].x][p[i].y] = true;
longitud--;
}
}return false;
}
public static void main(String[] args) {
Scanner x= new Scanner(system.in);
N = x.nextInt();
M = x.nextInt();
I = x.nextInt();
J = x.nextInt();
horseBETA yy = new horseBETA(N,J);
if(!yy.search())
System.out.println(\"\\nNo hay solucion\");
}
}
解决方法
以下是帮助您入门的提示:
从堆栈跟踪开始。跟踪的第一行显示:
at horseBETA.mover(horseBETA.java:55)
这意味着in6ѭ方法中发生了异常,该方法仅包含一行:
return new position(p.x+dx[i],p.y+dy[i]);
尝试取消引用空引用时,将引发NPE。上面一行中有4个子表达式,其中引用对象已取消引用,并且可能会发生NPE。
如果p
为null,则p.x
和p.y
可能会抛出NPE。
如果(13ѭ和dy
分别为空,则11ѭ或dy[i]
可能会抛出NPE。
通过简单地检查代码,可以排除其中四分之二的可能原因。 dx
和dy
被初始化为非空值,然后从不分配给它们。导致p
是null
的可能原因。 (您可以使用跟踪记录或调试器进行确认。)
现在交给您...
(我也同意@Speck。您的代码存在一些严重的样式问题,这使它难以阅读且难以调试...)
, 首先,您的代码难以辨认。如果使用可接受的样式准则,则在调试时会有所帮助。
需要改善的几件事:
使用名称而不是字母作为变量,并使用camelCaseVariables。这些将有助于提高可读性,尤其是在问这样的问题时。
对于语句和循环的一行也使用开括号和闭括号。它将更好地触发循环并使它们更具可读性,并有助于防止程序流程中的错误。
无论如何,您可能正在将一个空位置对象(将您的类名大写)传递给mover方法。在您的IDE中,在该行上设置一个断点,并使其有条件仅在传递的指针对象为null时才停止。您很快就会明白原因。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。