Reputation: 2102
I am writing code to simulate Non-deterministic finite automata. The program asks the user to input the NFA, followed by strings to test whether they belong to the NFA or not. However, the program keeps crashing due to this error:
java.lang.ArrayIndexOutOfBoundsException: 49
I've tried a lot to see if and where there's an overflow occurring, but I just can't figure it out.
My class 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;
}
}
And my main function:
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)"));
}
}
Any help in understanding the cause of the problem would be appreciated. Also, I'm a rookie at java, so my implementations might not be the best.
Upvotes: 2
Views: 1089
Reputation: 6531
I think the following code has some problems:
if(recursiveAccept(stringName, (""+transitionTable[currState].get(i)).charAt(2), currIndex))
return true;
You simply take the third character of the string. I assume the currState
can be 10, 11 etc.
Also I'd like to mention the following code:
String data = JOptionPane.showInputDialog("Enter transition for State"+i+" in the format 'alphabet-stateNumber':");
transitionTable[i].add(data);
No checks are done that data
is correct.
Anyway, the general advice is to debug the code to reproduce an error and find out why one of your automate arrays is being referenced at index greater than the number of states.
Upvotes: 1