2012-09-29 150 views
1

該程序應該以保存兩個鍵和下一個自動機信息的樹的形式製作非確定性自動機。自動機是在文本上找到模式(比這更明顯,但這應該滿足我的問題,因爲我還沒有進入下一部分)。我得到一個nullpointerexception,我找不到爲什麼

我不明白如何,但當我做一個簡單的模式爲自動機建立(「AA」是我的模式),我得到的「sgte」(下一個)變爲空,而數組的長度(保存爲N [千牛])不爲0,而且我找不到爲什麼:(

下面的代碼:

public class AFND { 

    private boolean estado; // true o false dependiendo de si es final o inicial respectivamente. 
    private AFND sgte[]; //arreglo con todos los posibles estados siguientes 
    private int N; //cantidad de posibles estados siguientes 
    private char key[]; //key[i] es el caracter con el que se accede a sgte[i] { '-' = e } 
    private int q; //denominador de estado 
    private String alfa = "aaabcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZZZ"; //para ahorrarnos errores revisamos indexOf desde la posicion 2 donde sea necesario 

    public AFND() { 
     estado = true; 
     sgte = null; 
     N = 0; 
     key = null; 
     q = 0; 
    } 

    public AFND(int q) { 
     estado = true; 
     sgte = null; 
     N = 0; 
     key = null; 
     this.q = q; 
    } 

    public AFND(String s) { 
     if (check(s) == false) { 
      U.println("Patrón Invalido."); 
      System.exit(0); 
     } 
     AFND k = Construccion(s, 0); 
     estado = k.estado; 
     int i = 0; 
     sgte = new AFND[k.N]; 
     key = new char[k.N]; 
     while (i < k.N) { 
      sgte[i] = k.sgte[i]; 
      key[i] = k.key[i]; 
      i++; 
     } 
     N = k.N; 
     q = k.q; 
    } 

    public AFND Construccion(String s, int l) { 
     if (s.length() == 0) { 
      return new AFND(); 
     } 
     AFND k = new AFND(l); 
     k.estado = false; 
     k.q = l; 
     if (s.charAt(0) == '[') { 
      AFND sgte[] = new AFND[5]; 
      char key[] = new char[5]; 
      String h = s.substring(1, s.indexOf(']')); 
      int i = 0; 
      int j = 0; 
      int x; 
      String L[] = new String[5]; 
      while (i < 5) { 
       L[i] = ""; 
       while (j < h.length()) { 
        x = alfa.substring(2).indexOf(h.charAt(j)); 
        L[i] += alfa.charAt(x + i - 2); 
        j++; 
       } 
       j = 0; 
       L[i] += s.substring(s.indexOf(']') + 1); 
       sgte[i] = Construccion(L[i].substring(1), l); 
       l++; 
       key[i] = L[i].charAt(0); 
       i++; 
      } 
      k.N = 5; 
     } else { 
      AFND sgte[] = new AFND[1]; 
      char key[] = new char[1]; 
      key[0] = s.charAt(0); 
      if (s.length() > 1) { 
       sgte[0] = Construccion(s.substring(1), l); 
      } else { 
       sgte[0] = new AFND(l); 
      } 
      k.N = 1; 
      l++; 
     } 
     int o = 0; 
     k.sgte = new AFND[k.N]; 
     k.key = new char[k.N]; 
     while (o < k.N) { 
      k.sgte[o] = sgte[o]; 
      k.key[o] = key[o]; 
      o++; 
     } 
     return k; 
    } 

    public boolean estado() { 
     return estado; 
    } 

    public AFND[] sgte() { 
     return sgte; 
    } 

    public int ancho() { 
     return N; 
    } 

    public char[] key() { 
     return key; 
    } 

    public int num() { 
     return q; 
    } 

    public boolean check(String s) { 
     int i = 0; 
     int j = 0; 
     while (i < s.length()) { 
      if (j == 0) { 
       if (s.charAt(i) == '[') { 
        j = 1; 
       } else if (s.charAt(i) == ']') { 
        return false; 
       } else if (!Character.isLetter(s.charAt(i))) { 
        return false; 
       } 
      } else { 
       if (s.charAt(i) == ']') { 
        j = 0; 
       } else if (s.charAt(i) == '[') { 
        return false; 
       } else if (!Character.isLetter(s.charAt(i))) { 
        return false; 
       } 
      } 
      i++; 
     } 
     return true; 
    } 
} 

而這裏的正在運行的程序:

import java.io.IOException; 

public class Tarea2 { 

static public void main(String[] args) throws IOException{ 
    String m=U.readLine("Ingresar Patrón: "); 
    AFND patron=new AFND(m); 
    U.println("AFND Patron Desplazado: "); 
    U.println(""); 
    U.println("<!--Deus ex Machina-->"); 
    U.println("<structure>"); 
    U.println("<type>"); 
    U.println("fa"); 
    U.println("</type>"); 
    U.println("<automaton>"); 
    imprimirEstados(patron); 
    imprimirTransiciones(patron); 
    U.println("</automaton>"); 
    U.println("</structure>"); 
} 

static public void imprimirEstados(AFND m){ 
    U.println("<state id="+m.num()+" name=q"+m.num()+">"); 
    U.println("<x>"); 
    U.println("0.0"); 
    U.println("</x>"); 
    U.println("<y>"); 
    U.println("0.0"); 
    U.println("</y>"); 
    U.println("</state>"); 
    int i=0; 
    if(m.ancho()!=0){ 
     AFND[] s=m.sgte(); 
     while(i<m.ancho()){ 
      imprimirEstados(s[i]); 
      i++; 
      } 
     } 
    } 

static public void imprimirTransiciones(AFND m){ 
    if(m.ancho()!=0){ 
     int i=0; 
     while(i<m.ancho()){ 
      U.println("<transition>"); 
      U.println("<from>"); 
      U.println(m.num()); 
      U.println("</from>"); 
      U.println("<to>"); 
      U.println(m.sgte()[i].num()); 
      U.println("</to>"); 
      U.println("<read>"); 
      U.println(m.key()[i]); 
      U.println("</read>"); 
      imprimirTransiciones(m.sgte()[i]); 
      i++; 
     } 
    } 
} 

} 

請幫助:(

這裏的例外:

Exception in thread "main" java.lang.NullPointerException 
at tarea2cs.AFND.Construccion(AFND.java:104) 
at tarea2cs.AFND.Construccion(AFND.java:95) 
at tarea2cs.AFND.<init>(AFND.java:48) 
at tarea2cs.Tarea2.main(Tarea2.java:9) 

104是這樣的部分: 「(!SGTE = NULL)如果」

 while(o<k.N){ 
     k.sgte[o]=sgte[o]; <= 
     k.key[o]=key[o]; 
     o++; 
    } 

我可以添加但不會解決問題,那它不應該變爲null:(

回答

3

我認爲這是一個陰影問題。你有一個實例變量sgte,但在幾個地方聲明局部變量具有相同的名稱;例如

AFND sgte[] = new AFND[5]; 

這看起來像一個錯誤......我的猜測應該是:(您在至少一種其他地方犯同樣的錯誤)

sgte = new AFND[5]; 


我還應該評論說,編寫的代碼具有嚴重的可維護性問題。如果沒有任何解釋性的註釋,你普遍使用一個字母的變量名和縮寫(如sgteAFND)將使其他人難以弄清楚這個應用程序是關於什麼的,更不用說它應該如何工作。

+0

在此評論上,我宣佈我對你的愛。你可能剛剛救了我的屁股。現在讓我們看看我能否完成這項工作。 Ty :) –

+0

這是我的計算理論課的作業。這不是爲某人使用而設計的,它只是處理問題的一種非常糟糕的方式,但它使用了我們在有關自動機的類中看到的。 我還沒有真正考慮代碼本身,只是試圖解決frkn的事情:( –

+0

那麼,如果他們正在標記你的代碼,他們*應該*標記風格以及功能的正確性。 ...你確實要求其他人閱讀代碼,即>>我們<<(我會批准你有評論,雖然我們大多數人都看不懂) –

1

您已經創建了一個數組,但您尚未創建對象。

sgte = new AFND[k.N]; 
for(int i=0;i<k.N;i++){ 
    sgte[i]=new AFND(); 
} 
1

您只創建了sgte數組,但從未初始化它。

private AFND sgte[]; //arreglo con todos los posibles estados siguientes 


    public AFND(int q) { 
    estado = true; 
    sgte = null; 
    N = 0; 
    key = null; 
    this.q = q; 
} 

和你想在0指數這裏

while (o < k.N) { 
     k.sgte[o] = sgte[o]; //NPE 
     k.key[o] = key[o]; 
     o++; 
    } 

得到元素,你也創建具有相同名稱的局部變量(它不是一個問題,反正)。 但是,爲了實例變量而使用this.sgte

+0

這是針對特定的當我用這種形式初始化的時候,它是專門用於樹的最後一片葉子:) –

相關問題