简体   繁体   中英

Searching for a list of words in a prefix tree

I am working on a project in which I need to build a prefix tree (trie). The trie should consist of a list of every combination of 4 capital letters (AAAA-ZZZZ). Searching in this tree should return a list of every possible answer (eg searching for "AAA" returns "AAAA", "AAAB", ... , "AAAZ")

As I do have trouble getting started with this I would love any suggestions from you guys.

Thank you very much for any help that you provide.

using System;
using System.Collections.Generic;

namespace Trees
{
    public class Program
    {
        public static void Main()
        {
            PrefixTree trie = new PrefixTree();
            trie.Add("AAAA");
            trie.Add("test");
            trie.Add("hello");
            trie.Add("help");
            trie.Add("hungary");

            Console.WriteLine(trie.Search("hel"));
        }
    }

    public class PrefixTree
    {
        private PrefixTreeNode root;

        public PrefixTree()
        {
            root = new PrefixTreeNode(String.Empty);
        }

        public void Add(string word)
        {
            AddRecursive(root, word, String.Empty);
        }

        private void AddRecursive(PrefixTreeNode node, string remainingString, string currentString)
        {
            if (remainingString.Length <= 0)
            {
                return;
            }

            char prefix = remainingString[0];
            string substring = remainingString.Substring(1);
            if (!node.SubNodes.ContainsKey(prefix))
            {
                node.SubNodes.Add(prefix, new PrefixTreeNode(currentString + prefix));
            }

            if (substring.Length == 0)
            {
                node.SubNodes[prefix].IsWord = true;
                return;
            }
            else
            {
                AddRecursive(node.SubNodes[prefix], substring, currentString + prefix);
            }
        }

        public IEnumerable<string> Search(string searchString)
        {
            PrefixTreeNode node = root;
            foreach (var search in searchString)
            {
                if (!node.SubNodes.ContainsKey(search))
                {
                    return new string[0];
                }
                node = node.SubNodes[search];
            }

            return FindAllWordsRecursive(node);
        }

        private IEnumerable<string> FindAllWordsRecursive(PrefixTreeNode node)
        {
            if (node.IsWord)
            {
                yield return node.Word;
            }

            foreach (var subnode in node.SubNodes)
            {
                foreach (var result in FindAllWordsRecursive(subnode.Value))
                {
                    yield return result;
                }
            }
        }

        protected class PrefixTreeNode
        {
            private readonly Dictionary<char, PrefixTreeNode> subNodes;
            private bool isWord;
            private readonly string word;

            public PrefixTreeNode(string word)
            {
                subNodes = new Dictionary<char, PrefixTreeNode>();
                isWord = false;
                this.word = word;
            }

            public Dictionary<char, PrefixTreeNode> SubNodes { get { return subNodes; } }
            public bool IsWord { get { return isWord; } set { isWord = value; } }
            public string Word { get { return word; } }
        }
    }
}

That's the code I have so far, but I don't know how to progress from that point to actually searching and retrieving what I'm looking for.

You could probably start with an array of the letters you wish to search on top of the original search.

string[] searchModifiers = { "A", "B", "C", "D", ... }

Then you could create a search function that iterates through that array and returns the results in whatever form you want (in this case, a string List).

public static List<string> DoSearch(string searchString)
{
    List<string> results = new List<string>();
    foreach(string modifier in searchModifiers)
        results.Add(searchString + modifier);
    return results;
}

I'm not sure about the parameters of your end result, but you could then fire this function in a recursive function that handles the parameters to what your desired end-result is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM