コード例 #1
0
        public static NFA CreateAutomaton(string a)
        {
            var result = new NFA();
            var start  = 0;
            var next   = 1;

            result.AddState(start, false);

            for (int i = 0; i < a.Length; ++i)
            {
                if (a[i] == '*')
                {
                    result.AddTransition(next - 1, next - 1, NFA.Any);
                }
                else
                {
                    result.AddState(next, false);
                    result.AddTransition(next - 1, next, (a[i] != '?' ? CharRange.SingleChar(a[i]) : NFA.Any));
                    ++next;
                }
            }

            result.AddState(next, true);
            result.AddTransition(next - 1, next, NFA.Epsilon);

            return(result);
        }
コード例 #2
0
        public static NFA CreateAutomaton(string a, int k)
        {
            if (a.Contains('*'))
            {
                throw new ArgumentException("Star is a reserved character");
            }

            var result = new NFA();
            var m      = a.Length + 1;

            /* Create |a|*k states */
            for (int i = 0; i < m; ++i)
            {
                for (int j = 0; j <= k; ++j)
                {
                    result.AddState(i + m * j, i == a.Length);
                }
            }

            /* Create transitions */
            for (int i = 0; i < m; ++i)
            {
                for (int j = 0; j <= k; ++j)
                {
                    if (i < m - 1)
                    {
                        result.AddTransition(i + m * j, i + 1 + m * j, CharRange.SingleChar(a[i]));
                    }

                    if (j < k)
                    {
                        if (i < m - 1)
                        {
                            result.AddTransition(i + m * j, i + 1 + m * (j + 1), NFA.Any);
                            result.AddTransition(i + m * j, i + 1 + m * (j + 1), NFA.Epsilon);
                        }

                        result.AddTransition(i + m * j, i + m * (j + 1), NFA.Any);
                    }
                }
            }

            return(result);
        }
コード例 #3
0
ファイル: DFA.cs プロジェクト: pombredanne/FullTextSearch
 public void AddTransition(int from, int to, CharRange c)
 {
     transitions[from].Add(new ValueTuple <CharRange, int>(c, to));
 }
コード例 #4
0
        public static IEnumerable <CharRange> Disjoin(this IEnumerable <CharRange> ranges)
        {
            var pqueue = new SortedSet <CharRange>(ranges, Comparer <CharRange> .Create((x, y) =>
            {
                if (x.start == y.start)
                {
                    return(y.end - x.end);
                }
                return(y.start - x.start);
            }));


            while (pqueue.Count > 1)
            {
                var current = pqueue.Max;
                pqueue.Remove(current);

                var next = pqueue.Max;
                if (current.end == next.start)
                {
                    pqueue.Remove(next);

                    if (current.start <= current.end - 1)
                    {
                        pqueue.Add(new CharRange(current.start, current.end - 1));
                    }

                    pqueue.Add(new CharRange(next.start, next.start));

                    if (next.start + 1 <= next.end)
                    {
                        pqueue.Add(new CharRange(next.start + 1, next.end));
                    }
                }
                else if (current.end > next.start)
                {
                    pqueue.Remove(next);

                    if (current.start < next.start)
                    {
                        var first = new CharRange(current.start, next.start - 1);
                        pqueue.Add(first);
                    }

                    var firstEnd = Math.Min(current.end, next.end);
                    var lastEnd  = Math.Max(current.end, next.end);

                    if (next.start <= firstEnd)
                    {
                        var second = new CharRange(next.start, firstEnd);
                        pqueue.Add(second);
                    }

                    if (firstEnd + 1 < lastEnd)
                    {
                        var third = new CharRange(firstEnd + 1, lastEnd);
                        pqueue.Add(third);
                    }
                }
                else
                {
                    yield return(current);
                }
            }

            if (pqueue.Count > 0)
            {
                yield return(pqueue.Max);
            }
        }