I'm implementing the non-deterministic finite automaton described in this post and this other post, using Konrad Rudolph's proposed algorithm.
Instead of using a C++ multimap, I used a HashSet<Character> [][] transitions
array (this is homework and Google's guava library cannot be used). The 1st dimension is the origin state, 2nd dimension is the destiny state and the HashSet defines the symbols for transition between origin and destiny states. The constructor for my Automaton class is:
Automaton (int numberOfStates)
{
this.numberOfStates = numberOfStates;
alphabet = new HashSet<>();
finalStates = new HashSet<>();
transitions = new HashSet[numberOfStates][numberOfStates];
for (int i = 0; i < numberOfStates; i++)
{
for (int j = 0; j < numberOfStates; j++)
{
transitions[i][j] = new HashSet<Character>();
}
}
}
This is my implementation of Konrad Rudolph's algorithm using this transitions array:
public String readStringInAutomaton (char[] inputString,
int initialState)
{
HashSet<Integer> currentStates = new HashSet<>();
HashSet<Integer> nextStates = new HashSet<>();
currentStates.add(initialState);
// for each char in inputString
for (int charIndex = 0; charIndex < inputString.length; charIndex++)
{
char currentTransitionChar = inputString[charIndex];
// for each state in currentStates
for (Integer originState : currentStates)
{
// for each transition starting from originState, current
// char
for (int destinyStateIndex = 0; destinyStateIndex < numberOfStates; destinyStateIndex++)
{
if (transitions[originState][destinyStateIndex]
.contains(currentTransitionChar))
{
nextStates.add(destinyStateIndex);
}
}
}
currentStates = nextStates;
}
}
I've tried replacing every instantiation of HashSet with Collections.synchronizedSet(new HashSet<>());
, as recommended in Oracle's HashSet documentation.
But then I get a java.lang.ArrayStoreException: java.util.Collections$SynchronizedSet when initializing transitions.
for (int i = 0; i < numberOfStates; i++)
{
for (int j = 0; j < numberOfStates; j++)
{
transitions[i][j] = Collections
.synchronizedSet(new HashSet<>());
}
}
How can I avoid these Concurrency exceptions?