我得到了一个nullpointerexception,我找不到原因

时间:2012-09-29 01:18:25

标签: java arrays tree nullpointerexception

该程序应该以树的形式制作一个非确定性自动机,其中包含两个键和下一个自动机的信息。自动机是在文本上找到模式(比这更复杂,但这应该足以解决我的问题,因为我还没有进入下一部分)。

我不明白怎么做但是当我为自动机构建一个简单的模式(“AA”是我的模式)时我得到的是“sgte”(下一个)变为null而数组的长度(保存)因为N [kN]不是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就是这部分:

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

我可以添加“if(sgte!= null)”,但这不能解决它在不应该变为空时的问题:(

3 个答案:

答案 0 :(得分:3)

我认为这是一个阴影问题。您有一个实例变量sgte,但在几个地方您声明了具有相同名称的局部变量; e.g。

   AFND sgte[] = new AFND[5];

这看起来像是一个错误......我的猜测应该是:

   sgte = new AFND[5];

(你在至少另一个地方犯了同样的错误。)


我还应该评论所写的代码存在严重的可维护性问题。您普遍使用一个字母变量名称和缩写(如sgteAFND)而没有任何解释性注释,这将使其他人很难弄清楚这个应用程序是什么,更不用说它是如何假设的工作。

答案 1 :(得分:1)

您已创建了一个数组,但尚未创建对象。

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

答案 2 :(得分: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 作为实例变量。