1

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

我不明白如何,但是当我为自动机构建一个简单的模式时(“AA”是我的模式),我得到“sgte”(next)在数组长度(保存为 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)”,但这并不能解决它不应该变成空的问题:(

4

3 回答 3

3

我认为这是一个阴影问题。你有一个实例变量sgte,但在几个地方你声明了同名的局部变量;例如

   AFND sgte[] = new AFND[5];

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

   sgte = new AFND[5];

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


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

于 2012-09-29T01:30:05.780 回答
1

您已经创建了一个数组,但还没有创建对象。

 sgte = new AFND[k.N];
 for(int i=0;i<k.N;i++){
   sgte[i]=new AFND();
 }
于 2012-09-29T01:29:38.203 回答
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作为实例变量。

于 2012-09-29T01:32:15.493 回答