private static void DFSserach(LenvstnDFA dfa, int start, TrieNode dictNode, List <string> output) { if (dfa.final.Contains(start) && dictNode.End) { output.Add(dictNode.Key); } Set <char> inputs = new Set <char>(); for (char ch = 'a'; ch <= 'z'; ++ch) { KeyValuePair <int, char> pair = new KeyValuePair <int, char>(start, ch); if (dfa.transTable.ContainsKey(pair)) { inputs.Add(ch); if (dictNode.Children.ContainsKey(ch)) { DFSserach(dfa, dfa.transTable[pair], dictNode.Children[ch], output); } } } if (dfa.defaultTrans.ContainsKey(start)) { foreach (char input in dictNode.Children.Keys) { if (!inputs.Contains(input)) { DFSserach(dfa, dfa.defaultTrans[start], dictNode.Children[input], output); } } } }
public static IEnumerable <string> Search(string oriWord, int maxDist, TrieDictionary dict) { LenvstnNFA nfa = LenvstnNFA.BuildNFA(oriWord, maxDist); //nfa.Show(); LenvstnDFA dfa = SubsetMachine.SubsetConstruct(nfa); //dfa.Show(); List <string> output = new List <string>(); DFSserach(dfa, dfa.start, dict.Root, output); return(output); }
public static LenvstnDFA SubsetConstruct(LenvstnNFA nfa) { ResetState(); LenvstnDFA dfa = new LenvstnDFA(); // Sets of NFA states which is represented by some DFA state Set <Set <state> > markedStates = new Set <Set <state> >(); Set <Set <state> > unmarkedStates = new Set <Set <state> >(); // Gives a number to each state in the DFA Dictionary <Set <state>, state> dfaStateNum = new Dictionary <Set <state>, state>(); Set <state> nfaInitial = new Set <state>(); nfaInitial.Add(nfa.initial); // Initially, EpsilonClosure(nfa.initial) is the only state in the DFAs states // and it's unmarked. Set <state> first = EpsilonClosure(nfa, nfaInitial); unmarkedStates.Add(first); // The initial dfa state state dfaInitial = GenNewState(); dfaStateNum[first] = dfaInitial; dfa.start = dfaInitial; while (unmarkedStates.Count != 0) { // Takes out one unmarked state and posteriorly mark it. Set <state> aState = unmarkedStates.Choose(); // Removes from the unmarked set. unmarkedStates.Remove(aState); // Inserts into the marked set. markedStates.Add(aState); // If this state contains the NFA's final state, add it to the DFA's set of // final states. if (aState.Where(state => nfa.final.Contains(state)).Count() > 0) { dfa.final.Add(dfaStateNum[aState]); } IEnumerator <input> iE = nfa.inputs.GetEnumerator(); // For each input symbol the NFA knows... while (iE.MoveNext()) { // Next state Set <state> next = EpsilonClosure(nfa, nfa.Move(aState, iE.Current)); if (next.IsEmpty) { continue; } // If we haven't examined this state before, add it to the unmarkedStates, // and make up a new number for it. if (!unmarkedStates.Contains(next) && !markedStates.Contains(next)) { unmarkedStates.Add(next); dfaStateNum.Add(next, GenNewState()); } if (iE.Current != (char)LenvstnNFA.Constants.Any && iE.Current != (char)LenvstnNFA.Constants.EpsilonAny) { KeyValuePair <state, input> transition = new KeyValuePair <state, input>(dfaStateNum[aState], iE.Current); dfa.transTable[transition] = dfaStateNum[next]; } else { if (!dfa.defaultTrans.ContainsKey(dfaStateNum[aState])) { dfa.defaultTrans.Add(dfaStateNum[aState], dfaStateNum[next]); } } } } return(dfa); }