예제 #1
0
        private void TestAndsplit(SuffNode node, int ichFirst, int ichLast, char ch, out bool fEnd, out SuffNode nodeNext)
        {
            if (ichFirst <= ichLast)
            {
                var edge = node.MpEdgeByCh[rgv[ichFirst - 1]];
                if (ch == rgv[edge.IchFirst + ichLast - ichFirst])
                {
                    fEnd     = true;
                    nodeNext = node;
                    return;
                }

                nodeNext = new SuffNode();
                nodeNext.AddEdge(edge.IchFirst + ichLast - ichFirst + 1, edge.IchLast, edge.Node, rgv[edge.IchFirst + ichLast - ichFirst]);
                edge.IchLast = edge.IchFirst + ichLast - ichFirst;
                edge.Node    = nodeNext;

                fEnd = false;
                return;
            }

            if (!node.MpEdgeByCh.ContainsKey(ch))
            {
                fEnd     = false;
                nodeNext = node;
                return;
            }

            fEnd     = true;
            nodeNext = node;
        }
예제 #2
0
        public SuffTree(List <char> rgabc, List <char> rgv)
        {
            this.rgv = rgv;

            Root  = new SuffNode();
            node0 = new SuffNode();
            for (var j = 1; j <= rgabc.Count; j++)
            {
                node0.AddEdge(-j, -j, Root, rgabc[j - 1]);
            }
            Root.SetSuffixLink(node0);

            var node    = Root;
            var ich     = 1;
            var ichNext = 0;

            while (ichNext != rgv.Count)
            {
                ichNext++;
                Update(ref node, ref ich, ichNext);
                Canonize(node, ich, ichNext, out node, out ich);

                //Console.WriteLine(t(i));
                //Console.WriteLine(root.TSTO(this));
                //Console.ReadLine();
            }
        }
예제 #3
0
        private void Update(ref SuffNode node, ref int ich, int ichNext)
        {
            var      nodePrev = Root;
            bool     fEnd;
            SuffNode nodeNext;

            TestAndsplit(node, ich, ichNext - 1, rgv[ichNext - 1], out fEnd, out nodeNext);
            while (!fEnd)
            {
                nodeNext.AddEdge(ichNext, rgv.Count, new SuffNode(), rgv[ichNext - 1]);
                if (nodePrev != Root)
                {
                    nodePrev.SetSuffixLink(nodeNext);
                }
                nodePrev = nodeNext;
                Canonize(node.NodeSuffix, ich, ichNext - 1, out node, out ich);
                TestAndsplit(node, ich, ichNext - 1, rgv[ichNext - 1], out fEnd, out nodeNext);
            }
            if (nodePrev != Root)
            {
                nodePrev.SetSuffixLink(node);
            }
        }
예제 #4
0
        private void Canonize(SuffNode node, int ichFirst, int ichLast, out SuffNode nodeNew, out int ichFirstNew)
        {
            if (ichLast < ichFirst)
            {
                nodeNew     = node;
                ichFirstNew = ichFirst;
                return;
            }

            var edge = node.MpEdgeByCh[rgv[ichFirst - 1]];

            while (edge.IchLast - edge.IchFirst <= ichLast - ichFirst)
            {
                ichFirst = ichFirst + edge.IchLast - edge.IchFirst + 1;
                node     = edge.Node;
                if (ichFirst <= ichLast)
                {
                    edge = node.MpEdgeByCh[rgv[ichFirst - 1]];
                }
            }

            nodeNew     = node;
            ichFirstNew = ichFirst;
        }
예제 #5
0
 public SuffEdge(int ichFirst, int ichLast, SuffNode node)
 {
     IchFirst = ichFirst;
     IchLast  = ichLast;
     Node     = node;
 }
예제 #6
0
 public void SetSuffixLink(SuffNode suffix)
 {
     NodeSuffix = suffix;
 }
예제 #7
0
 public void AddEdge(int ichFirst, int ichLast, SuffNode node, char ch)
 {
     MpEdgeByCh[ch] = new SuffEdge(ichFirst, ichLast, node);
 }