/// <summary> /// Basic Schulz and Mihov algoritm /// </summary> /// <returns>The correction nodes.</returns> /// <param name="typo">Typo.</param> /// <param name="start">Start.</param> /// <param name="editDistance">Edit distance.</param> /// <param name="includeOnlyWords">If set to <c>true</c> include only words.</param> IList<TrieNode> GetCorrectionNodes(string typo, TrieNode start, int editDistance, bool includeOnlyWords = true) { var corrections = new List<TrieNode> (); if (string.IsNullOrEmpty (typo)) { return corrections; } LevTAutomataImitation automata = new LevTAutomataImitation (typo, editDistance); Stack<SpellCheckerState> stack = new Stack<SpellCheckerState> (); stack.Push (new SpellCheckerState () { Node = start, AutomataState = 0, AutomataOffset = 0, }); while (stack.Count > 0) { SpellCheckerState state = stack.Pop(); automata.LoadState (state.AutomataState, state.AutomataOffset); AutomatonState nextZeroState = automata.GetNextState (0); foreach (char c in state.Node.Children.Keys) { AutomatonState nextState = null; if ((state.AutomataOffset < typo.Length && typo[state.AutomataOffset] == c) || (state.AutomataOffset < typo.Length - 1 && typo[state.AutomataOffset + 1] == c) || (state.AutomataOffset < typo.Length - 2 && typo[state.AutomataOffset + 2] == c)) { nextState = automata.GetNextState (automata.GetCharacteristicVector(c, state.AutomataOffset)); } else { nextState = nextZeroState; } if (nextState != null) { TrieNode nextNode = state.Node.Children [c]; if (nextNode.Children.Count > 0) { stack.Push (new SpellCheckerState () { Node = nextNode, AutomataState = nextState.State, AutomataOffset = nextState.Offset }); } if ((nextNode.IsWord || !includeOnlyWords) && automata.IsAcceptState (nextState.State, nextState.Offset)) { corrections.Add (nextNode); } } } } return corrections; }
/// <summary> /// Basic Schulz and Mihov algoritm /// </summary> /// <returns>The correction nodes.</returns> /// <param name="typo">Typo.</param> /// <param name="start">Start.</param> /// <param name="editDistance">Edit distance.</param> /// <param name="includeOnlyWords">If set to <c>true</c> include only words.</param> IList <TrieNode> GetCorrectionNodes(string typo, TrieNode start, int editDistance, bool includeOnlyWords = true) { var corrections = new List <TrieNode> (); if (string.IsNullOrEmpty(typo)) { return(corrections); } LevTAutomataImitation automata = new LevTAutomataImitation(typo, editDistance); Stack <SpellCheckerState> stack = new Stack <SpellCheckerState> (); stack.Push(new SpellCheckerState() { Node = start, AutomataState = 0, AutomataOffset = 0, }); while (stack.Count > 0) { SpellCheckerState state = stack.Pop(); automata.LoadState(state.AutomataState, state.AutomataOffset); AutomatonState nextZeroState = automata.GetNextState(0); foreach (char c in state.Node.Children.Keys) { AutomatonState nextState = null; if ((state.AutomataOffset < typo.Length && typo[state.AutomataOffset] == c) || (state.AutomataOffset < typo.Length - 1 && typo[state.AutomataOffset + 1] == c) || (state.AutomataOffset < typo.Length - 2 && typo[state.AutomataOffset + 2] == c)) { nextState = automata.GetNextState(automata.GetCharacteristicVector(c, state.AutomataOffset)); } else { nextState = nextZeroState; } if (nextState != null) { TrieNode nextNode = state.Node.Children [c]; if (nextNode.Children.Count > 0) { stack.Push(new SpellCheckerState() { Node = nextNode, AutomataState = nextState.State, AutomataOffset = nextState.Offset }); } if ((nextNode.IsWord || !includeOnlyWords) && automata.IsAcceptState(nextState.State, nextState.Offset)) { corrections.Add(nextNode); } } } } return(corrections); }