With the member variables that you have now, you can only represent a deterministic FSA. Why? Because a NDFSA is one where there is a state q1 and input a such that both
- (q1, a) -> q2
- (q1, a) -> q3
are in delta. You implement this (qfrom, input) -> qto mapping as int[][]
, which means that for each instate-input pair, you can only store one outstate.
One very quick fix would be to allow a list of outstates for all instate-input pair, like so:
ArrayList[][] delta;
However, this is ugly. We can arrive at a nicer solution* if you realize that delta is actually the mapping qfrom -> input -> qto, and it can be bracketed in two ways:
- (qfrom -> input) -> qto: this is what you had, with a little different notation
- qfrom -> (input -> qto)
Another thing to realize is that int[]
is conceptually the same as Map<Integer, Integer>
. With that, the second mapping can implemented in Java as:
Map<Integer, Map<Integer, List<Integer>>> delta;
Whichever implementation you choose, the test that decides if the FSA is deterministic or not is very simple, and comes from the definition: A is a DFSA iff the lengths of all lists in delta
are <= 1; otherwise, it is a NDFSA.
*Note that real FSA libraries usually use a different approach. For instance, foma uses an array of transition object with fields instate, outstate and the input character. However, for starters, the ones above are probably easier to handle.