java.lang.ArrayIndexOutOfBoundsException:49错误 - NFA Java

时间:2014-05-05 13:54:56

标签: java compiler-construction indexoutofboundsexception nfa

我正在编写代码来模拟非确定性有限自动机。该程序要求用户输入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的新手,所以我的实现可能不是最好的。

1 个答案:

答案 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是否正确。

无论如何,一般建议是调试代码以重现错误,并找出为什么在索引大于状态数时引用了一个自动化数组。