该程序应该以树的形式制作一个非确定性自动机,其中包含两个键和下一个自动机的信息。自动机是在文本上找到模式(比这更复杂,但这应该足以解决我的问题,因为我还没有进入下一部分)。
我不明白怎么做但是当我为自动机构建一个简单的模式(“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)”,但这不能解决它在不应该变为空时的问题:(
答案 0 :(得分:3)
我认为这是一个阴影问题。您有一个实例变量sgte
,但在几个地方您声明了具有相同名称的局部变量; e.g。
AFND sgte[] = new AFND[5];
这看起来像是一个错误......我的猜测应该是:
sgte = new AFND[5];
(你在至少另一个地方犯了同样的错误。)
我还应该评论所写的代码存在严重的可维护性问题。您普遍使用一个字母变量名称和缩写(如sgte
和AFND
)而没有任何解释性注释,这将使其他人很难弄清楚这个应用程序是什么,更不用说它是如何假设的工作。
答案 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 作为实例变量。