Exemple #1
0
        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);
        }
Exemple #2
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);
        }