private static void ApostropheEnd_C2_LetterPositions_BloomPrefix_Func_Bloom(Func <WordFeatureRow, bool> isWord_Word) { const int infixFreqsThreshold = 15; // Вычитание невозможных (и маловероятных) подстрок из 2х символов var notWordsC2strings = infixCalc.CalcInfixFreqs(wordFeatures, infixFreqsThreshold); solutionCreator.NotWordsC2strings = notWordsC2strings; // Вычитание невозможных символов на конкретных позициях var notPresentLetters = Enumerable.Range(0, wordFeatures.Max(f => f.Length)) .Select(i => wordFeatures.Where(f => f.Word.Length > i).Select(f => f.Word[i]).Distinct().ToArray()) .Select(a => new string(Alphabet.Except(a).ToArray())) .ToArray(); for (var i = 0; i < notPresentLetters.Length; i++) { if (notPresentLetters[i].Length > 0) { Console.WriteLine($"On position {i} can't use letters {notPresentLetters[i]}"); } } // Блюм фильтр возможных подстрок var substrBloomStarts = new[] { 0 }; var substrBloomCutLength = new[] { 3 }; var substrBloomMinLength = new[] { 4 }; var substrBlooms = Enumerable.Range(0, substrBloomStarts.Length) .Select(i => { var start = substrBloomStarts[i]; var minLength = substrBloomMinLength[i]; var cutLength = substrBloomCutLength[i]; var substrBloom = new BloomFilter(1000 * 8, 1); var substrs = wordFeatures.Where(f => f.Length >= minLength) .Select(f => start < 0 ? f.Word.Substring(f.Word.Length - cutLength, cutLength) : f.Word.Substring(start, cutLength)) .Distinct().ToArray(); foreach (var substr in substrs) { substrBloom.Add(substr); } substrBloom.ShowInfo(); return(substrBloom); }).ToArray(); solutionCreator.PrefixFilter = substrBlooms[0]; ApostropheEnd_Func_Bloom( isWord_Word, w => { if (w.C2Parts.Any(c2 => notWordsC2strings.Contains(c2))) { return(false); } var word = w.Word; for (var i = 0; i < word.Length; i++) { if (notPresentLetters[i].Contains(word[i])) { return(false); } } for (var i = 0; i < substrBloomStarts.Length; i++) { var start = substrBloomStarts[i]; var minLength = substrBloomMinLength[i]; var cutLength = substrBloomCutLength[i]; if (word.Length >= minLength && !substrBlooms[i].Contains(start < 0 ? word.Substring(word.Length - cutLength, cutLength) : word.Substring(start, cutLength))) { return(false); } } return(true); }, mainBloomLength * 8); }