private void FormChainOfGroups( ref List <GroupsTableRow> GroupsTable, ref List <GroupsTableRow> ResultGroups, int DataStringLength, int DepthOfRecursion = 0, GroupsTableRow PreviousGroup = null) { GroupsTableRow BestGroup = new GroupsTableRow(); if (GroupsTable.Count > 0) { GroupsTable = GroupsTable .OrderByDescending(x => x.GroupSize) .ThenBy(x => x.StartNumberInSearchStringWord) .ThenBy(x => x.StartNumberInDataStringWord) .ThenBy(x => x.DiagonalIndex) .ThenBy(x => x.NumberOfWordOfSearchString) .ToList(); BestGroup = GroupsTable[0]; } else { return; } ResultGroups.Add(BestGroup); if (Opt_DeleteIntersections == true) { RemoveIntersections(ref GroupsTable, ref BestGroup); } if (Opt_DeleteIntersectionsGroupsInWordsDatatringAndSearchString) { RemoveIntersectionsOfGroupsBySearchStringAndDataStringWords(ref GroupsTable, ref BestGroup); } GroupsTable.Remove(BestGroup); FormChainOfGroups(ref GroupsTable, ref ResultGroups, DataStringLength, DepthOfRecursion, BestGroup); }
private int CalculateRelevancePrivate() { if (this.SearchString == null || this.DataString == null) { Relevance = 0.0; return(0); } string SearchString = this.SearchString; string DataString = this.DataString; int SearchStringLength = SearchString.Length; int DataStringLength = DataString.Length; int SearchStringBorder; int DataStringBorder; SearchString = SearchString.ToLower(); DataString = DataString.ToLower(); if (SearchStringLength == 0 || DataStringLength == 0 || SearchStringLength > 200 || DataStringLength > 3000) { Relevance = 0.0; return(0); } string StringBuffer = ""; for (int i = 0; i < SearchStringLength; i++) { var SymbolOfRow = SearchString[i]; if (SymbolOfRow == ' ' || ThisIsUselessSymbol(SymbolOfRow)) { SymbolOfRow = ' '; } StringBuffer += SymbolOfRow; } SearchString = StringBuffer; if (DataStringLength < SearchStringLength) { StringBuffer = ""; for (int i = 1; i <= SearchStringLength - DataStringLength; i++) { StringBuffer += '♦'; } DataString += StringBuffer; DataStringLength = DataString.Length; } SearchStringBorder = SearchStringLength - 1; DataStringBorder = DataStringLength - 1; bool[] MatchMatrix = new bool[DataStringLength * SearchStringLength]; for (int i = 0; i <= DataStringBorder; i++) { for (int j = 0; j <= SearchStringBorder; j++) { if ( (SearchString[j] == DataString[i]) && SearchString[j] != ' ' ) { MatchMatrix[SearchStringLength * i + j] = true; } else { MatchMatrix[SearchStringLength * i + j] = false; } } } int DiagonalBorder; int StartIndexDiagonal; DiagonalBorder = DataStringBorder + SearchStringBorder; bool[] DiagonalsValueMatrix = new bool[(DiagonalBorder + 1) * SearchStringLength]; for (int i = 0; i <= DiagonalBorder; i++) { for (int j = 0; j <= SearchStringBorder; j++) { StartIndexDiagonal = i - SearchStringBorder + j; if (StartIndexDiagonal >= 0 && StartIndexDiagonal <= DataStringBorder) { DiagonalsValueMatrix[SearchStringLength * i + j] = MatchMatrix[SearchStringLength * StartIndexDiagonal + j]; } else { DiagonalsValueMatrix[SearchStringLength * i + j] = false; } } } List <GroupsTableRow> ResultGroups = new List <GroupsTableRow>(); WordsOfStringTableRow[] TableOfDataStringWords = new WordsOfStringTableRow[DataStringLength]; FillTableOfDataStringWords(ref DataString, ref TableOfDataStringWords, DataStringBorder); WordsOfStringTableRow[] TableOfSearchStringWords = new WordsOfStringTableRow[SearchStringLength]; FillTableOfDataStringWords(ref SearchString, ref TableOfSearchStringWords, SearchStringBorder); List <GroupsTableRow> GroupsTable = new List <GroupsTableRow>(); GroupsTableRow NewListItem; int CurrentGroupSize; for (int DiagonalIndex = 0; DiagonalIndex <= DiagonalBorder; DiagonalIndex++) { CurrentGroupSize = 0; for (int PositionInDiagonalIndex = 0; PositionInDiagonalIndex <= SearchStringBorder; PositionInDiagonalIndex++) { if (DiagonalsValueMatrix[SearchStringLength * DiagonalIndex + PositionInDiagonalIndex] == true) { CurrentGroupSize += 1; } else { if (CurrentGroupSize >= Opt_MinGroupSize) { var InitiallIndexInDiagonal = PositionInDiagonalIndex - CurrentGroupSize; var WordsTableRowSearchString = TableOfSearchStringWords[InitiallIndexInDiagonal]; var ThisIsInitialGroupOfSearchStringWord = WordsTableRowSearchString.NumberInWord == 1; var WordsTableRowDataString = TableOfDataStringWords[DiagonalIndex + InitiallIndexInDiagonal - SearchStringLength + 1]; var ThisIsInitialGroupOfDataStringWord = WordsTableRowDataString.NumberInWord == 1; if (Opt_ControlConformityAttributeInitialGroupWord == false || ThisIsInitialGroupOfSearchStringWord == ThisIsInitialGroupOfDataStringWord) { NewListItem = new GroupsTableRow(); NewListItem.DiagonalIndex = DiagonalIndex; NewListItem.InitiallIndexInDiagonal = InitiallIndexInDiagonal; NewListItem.FinalDiagonalIndex = PositionInDiagonalIndex - 1; NewListItem.GroupSize = CurrentGroupSize; NewListItem.GroupStartCoordinate = NewListItem.DiagonalIndex + NewListItem.InitiallIndexInDiagonal - SearchStringLength + 1; NewListItem.GroupEndCoordinate = NewListItem.GroupStartCoordinate + NewListItem.GroupSize - 1; NewListItem.NumberOfWordOfSearchString = WordsTableRowSearchString.NumberOfWord; NewListItem.StartNumberInSearchStringWord = WordsTableRowSearchString.NumberInWord; NewListItem.WordSizeOfSearchString = WordsTableRowSearchString.SizeOfWord; NewListItem.ThisIsInitialGroupOfSearchStringWord = ThisIsInitialGroupOfSearchStringWord; NewListItem.NumberOfWordOfDataString = WordsTableRowDataString.NumberOfWord; NewListItem.StartNumberInDataStringWord = WordsTableRowDataString.NumberInWord; NewListItem.WordSizeOfDataString = WordsTableRowDataString.SizeOfWord; NewListItem.ThisIsInitialGroupOfDataStringWord = ThisIsInitialGroupOfDataStringWord; GroupsTable.Add(NewListItem); } CurrentGroupSize = 0; } else { CurrentGroupSize = 0; } } } if (CurrentGroupSize >= Opt_MinGroupSize) { var InitiallIndexInDiagonal = SearchStringLength - CurrentGroupSize; var WordsTableRowSearchString = TableOfSearchStringWords[InitiallIndexInDiagonal]; var ThisIsInitialGroupOfSearchStringWord = WordsTableRowSearchString.NumberInWord == 1; var WordsTableRowDataString = TableOfDataStringWords[DiagonalIndex + InitiallIndexInDiagonal - SearchStringLength + 1]; var ThisIsInitialGroupOfDataStringWord = WordsTableRowDataString.NumberInWord == 1; if (Opt_ControlConformityAttributeInitialGroupWord == false || ThisIsInitialGroupOfSearchStringWord == ThisIsInitialGroupOfDataStringWord) { NewListItem = new GroupsTableRow(); NewListItem.DiagonalIndex = DiagonalIndex; NewListItem.InitiallIndexInDiagonal = InitiallIndexInDiagonal; NewListItem.FinalDiagonalIndex = SearchStringLength - 1; NewListItem.GroupSize = CurrentGroupSize; NewListItem.GroupStartCoordinate = NewListItem.DiagonalIndex + NewListItem.InitiallIndexInDiagonal - SearchStringLength + 1; NewListItem.GroupEndCoordinate = NewListItem.GroupStartCoordinate + NewListItem.GroupSize - 1; NewListItem.NumberOfWordOfSearchString = WordsTableRowSearchString.NumberOfWord; NewListItem.StartNumberInSearchStringWord = WordsTableRowSearchString.NumberInWord; NewListItem.WordSizeOfSearchString = WordsTableRowSearchString.SizeOfWord; NewListItem.ThisIsInitialGroupOfSearchStringWord = ThisIsInitialGroupOfSearchStringWord; NewListItem.NumberOfWordOfDataString = WordsTableRowDataString.NumberOfWord; NewListItem.StartNumberInDataStringWord = WordsTableRowDataString.NumberInWord; NewListItem.WordSizeOfDataString = WordsTableRowDataString.SizeOfWord; NewListItem.ThisIsInitialGroupOfDataStringWord = ThisIsInitialGroupOfDataStringWord; GroupsTable.Add(NewListItem); } } } FormChainOfGroups(ref GroupsTable, ref ResultGroups, DataStringLength); Relevance = CalculateCoefficient(ref TableOfSearchStringWords, SearchStringLength, DataStringLength, ref ResultGroups); if (Opt_FormingBriefRepresentationOfResult == true) { Stack <int> BriefDisplayCharactersOfDataString = new Stack <int>(); Stack <int> BriefFoundCharactersInDataString = new Stack <int>(); Stack <int> BriefFoundCharactersInDataStringExtended = new Stack <int>(); FillFoundFragments( ref ResultGroups, ref BriefDisplayCharactersOfDataString, ref BriefFoundCharactersInDataString, ref BriefFoundCharactersInDataStringExtended); BriefDisplayedFragments = BriefDisplayCharactersOfDataString.ToArray <int>(); Array.Sort <int>(BriefDisplayedFragments); var hashset = new HashSet <int>(); foreach (var x in BriefDisplayedFragments) { if (!hashset.Contains(x)) { hashset.Add(x); } } Array.Resize(ref BriefDisplayedFragments, hashset.Count); BriefDisplayedFragments = hashset.ToArray(); BriefDisplayOfFoundFragments = ""; int BriefDisplayedFragmentsLength = BriefDisplayedFragments.Length; int OriginalDataStringBorder = this.DataString.Length - 1; if (BriefDisplayedFragmentsLength > 0) { if (BriefDisplayedFragments[0] != 0) { BriefDisplayOfFoundFragments += "..."; } for (int i = 0; i < BriefDisplayedFragmentsLength; i++) { if (BriefDisplayedFragments[i] > OriginalDataStringBorder) { continue; } if (BriefFoundCharactersInDataString.Contains <int>(BriefDisplayedFragments[i])) { BriefDisplayOfFoundFragments += "<span class=\"findefragments\">" + this.DataString[BriefDisplayedFragments[i]] + "</span>"; } else { BriefDisplayOfFoundFragments += this.DataString[BriefDisplayedFragments[i]]; } if (i < BriefDisplayedFragmentsLength - 1 && BriefDisplayedFragments[i] + 1 != BriefDisplayedFragments[i + 1]) { BriefDisplayOfFoundFragments += "..."; } } if (BriefDisplayedFragments[BriefDisplayedFragmentsLength - 1] < OriginalDataStringBorder) { BriefDisplayOfFoundFragments += "..."; } } if (Opt_FormingFullRepresentationOfResult == true) { FullDisplayOfFoundFragments = ""; for (int i = 0; i <= OriginalDataStringBorder; i++) { if (BriefFoundCharactersInDataString.Contains <int>(i)) { { FullDisplayOfFoundFragments += "<span class=\"select1\">" + this.DataString[i] + "</span>"; } } else if (BriefFoundCharactersInDataStringExtended.Contains <int>(i)) { FullDisplayOfFoundFragments += "<span class=\"select2\">" + this.DataString[i] + "</span>"; } else { FullDisplayOfFoundFragments += this.DataString[i]; } } } } return(0); }
private void RemoveIntersectionsOfGroupsBySearchStringAndDataStringWords(ref List <GroupsTableRow> GroupsTable, ref GroupsTableRow BestGroup) { List <GroupsTableRow> DeletedRows = new List <GroupsTableRow>(); for (int i = 0; i < GroupsTable.Count; i++) { if (GroupsTable[i] == BestGroup) { continue; } if (GroupsTable[i].NumberOfWordOfSearchString == BestGroup.NumberOfWordOfSearchString && GroupsTable[i].NumberOfWordOfDataString != BestGroup.NumberOfWordOfDataString) { DeletedRows.Add(GroupsTable[i]); } else if (GroupsTable[i].NumberOfWordOfDataString == BestGroup.NumberOfWordOfDataString && GroupsTable[i].NumberOfWordOfSearchString != BestGroup.NumberOfWordOfSearchString) { DeletedRows.Add(GroupsTable[i]); } } for (int j = 0; j < DeletedRows.Count; j++) { GroupsTable.Remove(DeletedRows[j]); } }
private void RemoveIntersections(ref List <GroupsTableRow> GroupsTable, ref GroupsTableRow BestGroup) { List <GroupsTableRow> DeletedRows = new List <GroupsTableRow>(); int StartBestGroup, EndBestGroup, StartGroup, EndGroup, Difference; for (int i = 0; i < GroupsTable.Count; i++) { if (GroupsTable[i] == BestGroup) { continue; } if (BestGroup.NumberOfWordOfSearchString == GroupsTable[i].NumberOfWordOfSearchString) { StartBestGroup = BestGroup.StartNumberInSearchStringWord; EndBestGroup = BestGroup.StartNumberInSearchStringWord + BestGroup.GroupSize - 1; StartGroup = GroupsTable[i].StartNumberInSearchStringWord; EndGroup = GroupsTable[i].StartNumberInSearchStringWord + GroupsTable[i].GroupSize - 1; if (StartBestGroup < StartGroup && StartGroup <= EndBestGroup && EndBestGroup <= EndGroup) { Difference = EndBestGroup - StartGroup + 1; var tmp = GroupsTable[i]; tmp.InitiallIndexInDiagonal += Difference; tmp.GroupSize -= Difference; tmp.GroupStartCoordinate += Difference; tmp.StartNumberInSearchStringWord += Difference; tmp.StartNumberInDataStringWord += Difference; GroupsTable[i] = tmp; if (tmp.GroupSize == 0) { DeletedRows.Add(GroupsTable[i]); } } else if (StartGroup < StartBestGroup && StartBestGroup <= EndGroup && EndGroup <= EndBestGroup) { Difference = EndGroup - StartBestGroup + 1; var tmp = GroupsTable[i]; tmp.FinalDiagonalIndex -= Difference; tmp.GroupSize -= Difference; tmp.GroupEndCoordinate -= Difference; GroupsTable[i] = tmp; if (tmp.GroupSize == 0) { DeletedRows.Add(GroupsTable[i]); } } else if (StartGroup >= StartBestGroup && EndGroup <= EndBestGroup) { DeletedRows.Add(GroupsTable[i]); } } } for (int j = 0; j < DeletedRows.Count; j++) { GroupsTable.Remove(DeletedRows[j]); } DeletedRows.Clear(); for (int i = 0; i < GroupsTable.Count; i++) { if (GroupsTable[i] == BestGroup) { continue; } if (BestGroup.NumberOfWordOfDataString == GroupsTable[i].NumberOfWordOfDataString) { StartBestGroup = BestGroup.StartNumberInDataStringWord; EndBestGroup = BestGroup.StartNumberInDataStringWord + BestGroup.GroupSize - 1; StartGroup = GroupsTable[i].StartNumberInDataStringWord; EndGroup = GroupsTable[i].StartNumberInDataStringWord + GroupsTable[i].GroupSize - 1; if (StartBestGroup < StartGroup && StartGroup <= EndBestGroup && EndBestGroup <= EndGroup) { Difference = EndBestGroup - StartGroup + 1; var tmp = GroupsTable[i]; tmp.InitiallIndexInDiagonal += Difference; tmp.GroupSize -= Difference; tmp.GroupStartCoordinate += Difference; tmp.StartNumberInSearchStringWord += Difference; tmp.StartNumberInDataStringWord += Difference; GroupsTable[i] = tmp; if (tmp.GroupSize == 0) { DeletedRows.Add(GroupsTable[i]); } } else if (StartGroup < StartBestGroup && StartBestGroup <= EndGroup && EndGroup <= EndBestGroup) { Difference = EndGroup - StartBestGroup + 1; var tmp = GroupsTable[i]; tmp.FinalDiagonalIndex -= Difference; tmp.GroupSize -= Difference; tmp.GroupEndCoordinate -= Difference; GroupsTable[i] = tmp; if (tmp.GroupSize == 0) { DeletedRows.Add(GroupsTable[i]); } } else if (StartGroup >= StartBestGroup && EndGroup <= EndBestGroup) { DeletedRows.Add(GroupsTable[i]); } } } for (int j = 0; j < DeletedRows.Count; j++) { GroupsTable.Remove(DeletedRows[j]); } }