コード例 #1
0
        private static void WriteInMissingTransitions(StateGraph.Node node, StateGraph graph, List <int> sequenceReversed)
        {
            // the sequence is in reversed order which is kinda unnatural, but the Stack<> container does not have index-based
            // access, thus I'm using List<> adding to and removing from its back

            var t = node.Transitions;

            for (int i = 0; i < t.Length; ++i)
            {
                sequenceReversed.Add(i);

                StateGraph.Node transitionNode = t[i];

                if (transitionNode != null)
                {
                    WriteInMissingTransitions(transitionNode, graph, sequenceReversed);
                }
                else
                {
                    t[i] = graph.FindNode(sequenceReversed);
                }

                sequenceReversed.RemoveLast();
            }
        }
コード例 #2
0
        private static void WriteInMissingSequenceIndices(StateGraph.Node node, StateGraph graph, List <int> sequenceReversed)
        {
            if (node.SequenceIndex < 0)
            {
                node.SequenceIndex = graph.FindNode(sequenceReversed).SequenceIndex;
            }

            var t       = node.Transitions;
            var tLenght = t.Length;

            if (tLenght != graph.AlphabetSize)
            {
                throw new ArgumentException("Node transition count is not consistent with the alphabet size");
            }

            for (int i = 0; i < tLenght; ++i)
            {
                sequenceReversed.Add(i);

                var transitionNode = t[i];

                if (transitionNode != null)
                {
                    WriteInMissingSequenceIndices(transitionNode, graph, sequenceReversed);
                }

                sequenceReversed.RemoveLast();
            }
        }
コード例 #3
0
        public void AcceptSymbol(int symbol)
        {
            try
            {
                _currentNode = _currentNode.Transitions[symbol];
            }
            catch (IndexOutOfRangeException e)
            {
                throw new ArgumentException("symbol is out of state range", e);
            }

            Symbol = symbol;
        }
コード例 #4
0
        private static void PrintGraphExpressionRecursive(StateGraph.Node root, StringBuilder sb, HashSet <StateGraph.Node> visitedNodes)
        {
            if (visitedNodes.Contains(root))
            {
                sb.Append($"(~{root.PrintCore()}");
            }
            else
            {
                sb.Append($"({root.PrintCore()}");

                visitedNodes.Add(root);

                if (root.Transitions.Any(n => n != null))
                {
                    sb.Append(">");
                }

                var t = root.Transitions;

                for (int i = 0; i < t.Length; ++i)
                {
                    var transitionNode = t[i];

                    if (transitionNode == null)
                    {
                        continue;
                    }

                    sb.Append($"{i}'");

                    PrintGraphExpressionRecursive(transitionNode, sb, visitedNodes);
                }
            }

            sb.Append(")");
        }
コード例 #5
0
        public static void BuildTrie(this StateGraph graph, int[][] sequences)
        {
            if (sequences == null)
            {
                throw new ArgumentNullException(nameof(sequences));
            }

            var root = graph.Root;

            var nodeIndex     = 1;
            var sequenceIndex = 1;
            var alphabetSize  = graph.AlphabetSize;

            for (int i = 0; i < alphabetSize; ++i)
            {
                root.Transitions[i] = new StateGraph.Node(alphabetSize, nodeIndex++)
                {
                    SequenceIndex = sequenceIndex++
                }
            }
            ;

            for (int k = 0; k < sequences.Length; ++k)
            {
                var sequence = sequences[k]
                               ?? throw new ArgumentNullException($"sequence {sequenceIndex}");

                var lastSymbolIndex = sequence.Length - 1;

                if (lastSymbolIndex < 0)
                {
                    throw new ArgumentException($"sequence {sequenceIndex} is empty");
                }

                var currentNode = root;

                for (int j = 0; j <= lastSymbolIndex; ++j)
                {
                    var symbol = sequence[j];

                    if (symbol >= alphabetSize || symbol < 0)
                    {
                        throw new ArgumentException($"symbol {symbol} at index {j} of sequence {sequenceIndex} is out of the boundaries of the alphabet");
                    }

                    var t = currentNode.Transitions;

                    StateGraph.Node childNode = t[symbol];

                    if (childNode == null)
                    {
                        childNode = new StateGraph.Node(alphabetSize, nodeIndex++);
                        t[symbol] = childNode;
                    }

                    if (j == lastSymbolIndex)
                    {
                        if (childNode.SequenceIndex == -1)
                        {
                            childNode.SequenceIndex = sequenceIndex++;
                        }
                        else
                        {
                            throw new ArgumentException($"sequence {sequenceIndex} is equal to sequence {childNode.SequenceIndex}");
                        }
                    }

                    currentNode = childNode;
                }
            }

            graph.StateCount = nodeIndex;
        }
コード例 #6
0
 public void Reset()
 {
     _currentNode = Graph.Root;
     Symbol       = StateGraph.DefaultSymbol;
 }