/// <summary> /// Finds possible starting <see cref="SequenceSearchState{T}"/>s for sequence searching in the <see cref="MinimalDAG{T}"/> /// </summary> /// <param name="valuePool"></param> /// <param name="index"></param> /// <param name="pattern"></param> /// <param name="wildCardCount"></param> /// <returns></returns> private IEnumerable <SequenceSearchState <char> > FindSearchStartPoints(List <char> valuePool, int index, Pattern <char> pattern, int wildCardCount) { IEnumerable <IMinimalDAGNode <char> > PossibleStartNodes; var ValidStartValues = pattern.SearchSpace[index]; if (!pattern.IsIndexForcedEmpty(index)) { if (ValidStartValues.Count == 1) { if (pattern.TryGetHardPrefixLimit(index, out int prefixIndex) || index == 0) //hard prefix limit { index = prefixIndex; PossibleStartNodes = _dawg.GetAllValidStartNodes().Where(x => x.Value.Equals(pattern.SearchSpace[index].First())); } else if (index > 0 && pattern.TryGetHardPrefixLimit(index - 1, out int softPrefixIndex)) //soft prefix limit { if (pattern.SearchSpace[softPrefixIndex] != null) { PossibleStartNodes = _dawg.GetAllValidStartNodes().Where(x => x.Value.Equals(pattern.SearchSpace[softPrefixIndex].First())); var FurtherPossibleStartNodes = _dawg.GetAllValidStartNodes().Where(x => x.Value.Equals(pattern.SearchSpace[index].First())); PossibleStartNodes = PossibleStartNodes.Concat(FurtherPossibleStartNodes); } else { PossibleStartNodes = _dawg.GetAllNodesWithValue(pattern.SearchSpace[index].First()); } } else { PossibleStartNodes = _dawg.GetAllNodesWithValue(pattern.SearchSpace[index].First()); } foreach (var Node in PossibleStartNodes) { yield return(new SequenceSearchState <char>(Node, valuePool, index, wildCardCount)); } } else { foreach (var ValidStart in ValidStartValues) { if (!ValidStart.Equals(pattern.EmptyValue)) { PossibleStartNodes = _dawg.GetAllNodesWithValue(ValidStart); var UsedDict = new Dictionary <int, char>(); UsedDict.Add(index, ValidStart); if (wildCardCount > 0) { List <int> WildCardIndices = new List <int>() { index }; foreach (var PossibleStartNode in PossibleStartNodes) { yield return(new SequenceSearchState <char>(PossibleStartNode, valuePool, index, wildCardCount - 1, UsedDict, WildCardIndices)); } } if (valuePool.Contains(ValidStart)) { var UpdatedPool = new List <char>(valuePool); UpdatedPool.Remove(ValidStart); foreach (var PossibleStartNode in PossibleStartNodes) { yield return(new SequenceSearchState <char>(PossibleStartNode, UpdatedPool, index, wildCardCount, UsedDict)); } } } } } } }
/// <summary> /// Finds possible starting <see cref="SequenceSearchState{T}"/>s for sequence searching in the <see cref="IMinimalDAG{T}"/> /// </summary> /// <param name="valuePool"></param> /// <param name="index"></param> /// <param name="pattern"></param> /// <param name="wildCardCount"></param> /// <returns></returns> private IEnumerable <SequenceSearchState <T> > FindSearchStartPoints(IEnumerable <T> valuePool, int index, IPattern <T> pattern, int wildCardCount) { //var PrefixBoundaries = FindValidBoundaryPositions(-1, pattern); //var SuffixBoundaries = FindValidBoundaryPositions(1, pattern); IEnumerable <IMinimalDAGNode <T> > PossibleStartNodes; var ValidStartValues = pattern.SearchSpace[index]; if (ValidStartValues.Count == 1) { if (pattern.TryGetHardPrefixLimit(index, out int prefixIndex) || index == 0) { index = prefixIndex; PossibleStartNodes = _dag.GetAllValidStartNodes().Where(x => x.Value.Equals(pattern.SearchSpace[index].First())); } else if (index > 0 && pattern.TryGetHardPrefixLimit(index - 1, out int softPrefixIndex)) //soft prefix limit { PossibleStartNodes = _dag.GetAllValidStartNodes().Where(x => x.Value.Equals(pattern.SearchSpace[softPrefixIndex].First())); var FurtherPossibleStartNodes = _dag.GetAllValidStartNodes().Where(x => x.Value.Equals(pattern.SearchSpace[index].First())); PossibleStartNodes = PossibleStartNodes.Concat(FurtherPossibleStartNodes); } else { PossibleStartNodes = _dag.GetAllNodesWithValue(pattern.SearchSpace[index].First()); } foreach (var Node in PossibleStartNodes) { yield return(new SequenceSearchState <T>(Node, valuePool, index, wildCardCount)); } } else { foreach (var ValidStart in ValidStartValues) { PossibleStartNodes = _dag.GetAllNodesWithValue(ValidStart); var UsedDict = new Dictionary <int, T>(); UsedDict.Add(index, ValidStart); if (wildCardCount > 0) { List <int> WildCardIndices = new List <int>() { index }; foreach (var PossibleStartNode in PossibleStartNodes) { yield return(new SequenceSearchState <T>(PossibleStartNode, valuePool, index, wildCardCount - 1, UsedDict, WildCardIndices)); } } if (valuePool.Contains(ValidStart)) { var UpdatedPool = valuePool.ExceptFirst(ValidStart); foreach (var PossibleStartNode in PossibleStartNodes) { yield return(new SequenceSearchState <T>(PossibleStartNode, UpdatedPool, index, wildCardCount, UsedDict)); } } } } }