我正在编写代码来模拟非确定性有限自动机。该程序要求用户输入NFA,然后输入字符串以测试它们是否属于NFA。 但是,由于此错误,程序不断崩溃:
java.lang.ArrayIndexOutOfBoundsException:49
我已经尝试了很多,看看是否以及哪里出现溢出,但我无法弄明白。
我的班级NFA:
public static class NFA
{
int numStates;
int alphabetSize;
char[] alphabets;
LinkedList[] transitionTable;
boolean[] isFinal;
NFA()
{
numStates = Integer.parseInt(JOptionPane.showInputDialog("Enter Number of States: "));
alphabetSize = Integer.parseInt(JOptionPane.showInputDialog("Enter Number of Alphabets, including epsilon transition 'e': "));
alphabets = new char[alphabetSize];
alphabets[0] = 'e';
for(int i=1;i<alphabetSize;i++)
{
alphabets[i] = (JOptionPane.showInputDialog("Enter alphabet "+i+": ")).charAt(0);
for(int j=0;j<i;j++)
{
System.out.print(alphabets[j]+" "+alphabets[i]);
if(alphabets[j]==alphabets[i])
{
JOptionPane.showMessageDialog(null,"Alphabet '"+alphabets[i]+"' already exists in the alphabet space! Enter some other alphabet.");
i--;
break;
}
}
}
transitionTable = new LinkedList[numStates];
for(int i=0;i<numStates;i++)
{
transitionTable[i] = new LinkedList();
int ch = Integer.parseInt(JOptionPane.showInputDialog("Do you want to add any transition(s) for state s"+i+"? (Y=1, N=0)"));
while(ch == 1)
{
String data = JOptionPane.showInputDialog("Enter transition for State"+i+" in the format 'alphabet-stateNumber':");
transitionTable[i].add(data);
System.out.println("S"+i+": "+transitionTable[i]);
ch = Integer.parseInt(JOptionPane.showInputDialog("Do you want to add more transitions for state s"+i+"? (Y=1, N=0)"));
}
}
isFinal = new boolean[numStates];
for(int k=0;k<numStates;k++)
{
int ans = Integer.parseInt(JOptionPane.showInputDialog("Is s"+k+" an accept state?(1=Y, 0=N)"));
if(ans == 1)
{
isFinal[k] = true;
}
else isFinal[k] = false;
}
}
private boolean accepts(String stringName) {
if(stringName.equals(""))
{
if(isFinal[0]) return true;
else return false;
}
int startState = 0;
return recursiveAccept(stringName, startState, 0);
}
private boolean recursiveAccept(String stringName, int currState, int currIndex)
{
System.out.println("\t\tcurrIndex:"+currIndex+"\tlength() == "+stringName.length());
if(currIndex == stringName.length())
{
if(isFinal[currState])
return true;
else if(transitionTable[currState].size() == 0)
{
return false;
//String[] s = (String[]) transitionTable[currState].toArray();
}
else
{
for(int i=0;i<transitionTable[currState].size();i++)
{
if((""+transitionTable[currState].get(i)).charAt(0) == 'e')
{
System.out.println("\t\tEntered line 114");
if(recursiveAccept(stringName, (""+transitionTable[currState].get(i)).charAt(2), currIndex))
return true;
}
}
}
return false;
}
if(transitionTable[currState].size()==0) //&& currIndex<(stringName.length()-1))
return false;
else
{
for(int i=0;i<transitionTable[currState].size();i++)
{
System.out.println("\t\tLoop at line 129...linked list element : "+transitionTable[currState].get(i));
if((""+transitionTable[currState].get(i)).charAt(0) == 'e')
{
if(recursiveAccept(stringName, (""+transitionTable[currState].get(i)).charAt(2), currIndex))
return true;
}
else if((""+transitionTable[currState].get(i)).charAt(0) == stringName.charAt(currIndex))
{
if(recursiveAccept(stringName, (""+transitionTable[currState].get(i)).charAt(2), currIndex+1))
return true;
}
}
}
return false;
}
}
我的主要职能是:
public static void main(String[] args) {
// TODO code application logic here
NFA objectName = new NFA();
int choice = 1;
while (choice == 1 )
{
String stringName = JOptionPane.showInputDialog("Enter String :");
//String stringName = "111";
if(objectName.accepts(stringName))
System.out.print(stringName+" is accepted!");
else System.out.print(stringName+" not accepted!");
choice = Integer.parseInt(JOptionPane.showInputDialog("Enter more?(1=Y, 0=N)"));
}
}
任何帮助理解问题的原因将不胜感激。 另外,我是java的新手,所以我的实现可能不是最好的。
答案 0 :(得分:1)
我认为以下代码存在一些问题:
if(recursiveAccept(stringName, (""+transitionTable[currState].get(i)).charAt(2), currIndex))
return true;
你只需要取字符串的第三个字符。我假设currState
可以是10,11等。
另外我想提一下以下代码:
String data = JOptionPane.showInputDialog("Enter transition for State"+i+" in the format 'alphabet-stateNumber':");
transitionTable[i].add(data);
没有检查data
是否正确。
无论如何,一般建议是调试代码以重现错误,并找出为什么在索引大于状态数时引用了一个自动化数组。