/// <summary> /// Рекурсивный метод заполнения дерева /// </summary> private static void Add(string item, int index, MyDictionaryTree three) { // когда уровень вложенности равен длине слова - сохраняем его if (item.Length == index) { three.word = item; } else { // Проверяем существование у узла потомка с заданным символом var isChild = three.nextLevel.Any(x => x.key == item[index]); // Добавляем при необходимости потомка if (!isChild) { three.nextLevel.Add(new MyDictionaryTree() { key = item[index], nextLevel = new List <MyDictionaryTree>() }); } // Только что созданного потомка(или существовавшего) передаем в рекурс. метод var child = three.nextLevel.FirstOrDefault(x => x.key == item[index]); if (child != null) { Add(item, index + 1, child); } } }
/// <summary> /// По маске выполняет поиск в дереве /// </summary> private static List <string> GetWordsFromTree(string mask, int index, MyDictionaryTree three, char[] stopChar) { // если глубина нахождения в дереве уже равна длине маски - возвращаем слово if (mask.Length == index) { return(new List <string> { three.word }); } else { if (mask[index] == '*') { // Для неизвестного символа - берем все символы на данном уровне // Вызываем для них рекурсивный метод - переходим не следующий уровень дерева var result = new List <string>(); foreach (var child in three.nextLevel.Where(x => !stopChar.Contains(x.key))) { result.AddRange(GetWordsFromTree(mask, index + 1, child, stopChar)); } return(result); } else { var child = three.nextLevel.FirstOrDefault(x => x.key == mask[index]); if (child != null) { // переходим не следующий уровень дерева для определенного символа return(GetWordsFromTree(mask, index + 1, child, stopChar)); } return(new List <string>()); } } }
public static void Init(string[] wordsArr) { // Инициализируем корень дерева myTree = new MyDictionaryTree() { nextLevel = new List <MyDictionaryTree>() }; // Добавляем каждое слово из словаря в дерево foreach (var item in wordsArr) { Add(item.ToLower(), 0, myTree); } }