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); }
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); }
public void AddTransition(int from, int to, CharRange c) { transitions[from].Add(new ValueTuple <CharRange, int>(c, to)); }
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); } }