2012-09-29 55 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

这是针对特定的当我用这种形式初始化的时候,它是专门用于树的最后一片叶子:) –

相关问题