2

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

4

1 回答 1

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正确的检查。

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

于 2014-05-05T14:05:13.420 回答