private static int CompareOutputs(LinkedByteArrayListNode a, LinkedByteArrayListNode b) { if (a.ByteCount != b.ByteCount) { return(a.ByteCount.CompareTo(b.ByteCount)); } // TODO : implement lexicographical ordering. return(0); }
public byte[] GetMinimumOutput(byte[] input) { LinkedByteArrayListNode[] stateOutputs = new LinkedByteArrayListNode[_states.Length]; for (int i = 0; i < _states.Length; i++) { if (_states[i].StartOutput != null) { stateOutputs[i] = new LinkedByteArrayListNode { Output = _states[i].StartOutput, ByteCount = _states[i].StartOutput.Length, }; } } foreach (byte b in input) { LinkedByteArrayListNode[] newStateOutputs = new LinkedByteArrayListNode[_states.Length]; for (int i = 0; i < _states.Length; i++) { if (stateOutputs[i] != null) { if (!_states[i].Transitions.TryGetValue(b, out var transitions)) { continue; } foreach (var transition in transitions) { var dest = transition.NextState; var newOutput = new LinkedByteArrayListNode { Output = transition.Output, PrevNode = stateOutputs[i], ByteCount = stateOutputs[i].ByteCount + transition.Output.Length, }; if (newStateOutputs[dest] == null || CompareOutputs(newStateOutputs[dest], newOutput) > 0) { newStateOutputs[dest] = newOutput; } } } } stateOutputs = newStateOutputs; } LinkedByteArrayListNode outputNode = null; for (int i = 0; i < _states.Length; i++) { if (_states[i].IsAccept && stateOutputs[i] != null) { if (outputNode == null || CompareOutputs(outputNode, stateOutputs[i]) > 0) { outputNode = stateOutputs[i]; } } } if (outputNode == null) { return(null); } byte[] output = new byte[outputNode.ByteCount]; int outputIndex = output.Length; while (outputNode != null) { outputIndex -= outputNode.Output.Length; Array.Copy(outputNode.Output, 0, output, outputIndex, outputNode.Output.Length); outputNode = outputNode.PrevNode; } if (outputIndex != 0) { throw new Exception("Internal error: ByteCount of LinkedByteArrayListNode was wrong?"); } return(output); }