2011-06-25 9 views
1

次のコードは、10x10または8x8チェス盤でポジション0 0で開始されたときチェスボード内のナイトの正しいハミルトニアンサイクルを見つけますが、他の場所で開始されたときはNullPointerExceptionをスローします。NullPointerExceptionこのハミルトニアンサイクルの問題

8 
8 
1 
1 

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 

:ここで

入力が正しい出力を実行する位置0で始まる8×8のチェス盤、上のハミルトニアンサイクルの

8 
8 
0 
0 

なければなりません私は得る:

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, -2, -1, 1, 2, 2, 1}; 
    static int dy[] = {-2, -1, 1, 2, 2, 1, -1, -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,M,I,J); 
     if(!yy.search()) 
      System.out.println("\nNo hay solucion"); 

    } 
} 

答えて

4

あなたが始めるためにヒントです:スタックトレースを持つ

スタート。トレースの最初の行は言う:

at horseBETA.mover(horseBETA.java:55) 

これは、例外はmover方法で発生したことを意味し、その方法は、ただ一つのラインで構成されています試みがあるときにNPEがスローされ

return new position(p.x+dx[i],p.y+dy[i]); 

ヌル参照を間接参照するように作られています。上記の行には、オブジェクト参照が間接参照される4つのサブ式があり、NPEが発生する可能性があります。

  • p.xp.ypがnullの場合は、NPEを投げることができました。 (それぞれ)dxdyがnullの場合

  • dx[i]またはdy[i]はNPEをスローする可能性があります。

これらの考えられる原因のうち2つは、コードの単純な検査で除外することができます。 dxおよびdyは、null以外の値に初期化され、次に割り当てられません。その結果、pnullになる可能性があります。 (あなたがTracePrintのか、デバッガを使用してこれを確認することができます。)

を今以上のあなたに...


(私も@Speckに同意します。あなたの持ついくつかの深刻なスタイルの問題を持っていますコードを読みにくくてデバッグが難しい...)

+0

**モデレータ注:**この回答のコメントは、ノイズに劣化しているため削除されました。コメントは専門家、建設的、トピックにしてください。 –

0

まず、コードが読みにくいです。受け入れられたスタイルガイドラインを使用すると、デバッグ時に役立ちます。

改善を支援するために物事のカップル:

使っ名ではない変数や好意のcamelCaseVariablesのための文字。これらは、特にこのような質問をする際の読みやすさを助けます。

if文とループが1つ並んでいる場合でも、開いた括弧と閉じ括弧を使用します。ループを設定して読みやすくし、プログラムフローのバグを防ぐのに役立ちます。

とにかく、ヌル位置オブジェクト(クラス名btwを大文字にする)をムーバーメソッドに渡している可能性があります。 IDEで、その行にブレークポイントを設定し、渡されたポインタオブジェクトがnullの場合にのみ停止するよう条件付きにします。理由をすぐに知ることができます。