Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用.NET StringDictionary在列表/字典中搜索前缀?_C#_String_Search_Prefix - Fatal编程技术网

C# 使用.NET StringDictionary在列表/字典中搜索前缀?

C# 使用.NET StringDictionary在列表/字典中搜索前缀?,c#,string,search,prefix,C#,String,Search,Prefix,我想知道.NET是否提供了通过列表或字典对象进行前缀搜索的标准功能。我偶然发现了StringDictionary,但不知道它是否能帮我做到这一点 如果它可以做前缀搜索,它也可以做子字符串搜索,或者让我用正则表达式之类的东西来搜索 提前感谢。我认为StringDictionary不支持前缀搜索,但是如果使用SortedList可以在键的范围内进行二进制搜索,直到找到前缀前后的第一个条目。我认为StringDictionary是一个老派(预泛型)。您可能应该使用字典(字符串,字符串),因为它实现了I

我想知道.NET是否提供了通过列表或字典对象进行前缀搜索的标准功能。我偶然发现了
StringDictionary
,但不知道它是否能帮我做到这一点

如果它可以做前缀搜索,它也可以做子字符串搜索,或者让我用正则表达式之类的东西来搜索


提前感谢。

我认为StringDictionary不支持前缀搜索,但是如果使用
SortedList
可以在键的范围内进行二进制搜索,直到找到前缀前后的第一个条目。

我认为
StringDictionary
是一个老派(预泛型)。您可能应该使用
字典(字符串,字符串)
,因为它实现了IEnumerable(想想LINQ)。一个极端的问题是它不区分大小写。

StringDictionary
只是一个哈希表,其中键和值是
string
s。这在泛型之前就存在了(当
字典
不可能时)

这里需要的数据结构是一个。有以下方面的实现:


  • 或者,如果你是那种人,那就自己动手吧(请参见)。

    我为这一点提供了一个通用的实现


    由于
    string
    实现了
    IEnumerable
    ,因此您可以将它与
    char
    一起用作
    TKeyElement

    的参数。下面是一组字符串的基本实现,可以通过前缀进行有效搜索

    其思想是将集合中的所有单词保留在一个trie中,当查询以查找以某个前缀开头的所有单词时,我们会找到前缀中最后一个字符对应的节点,然后在DFS中收集并返回其所有子体

    public class PrefixSearchableSet
    {
        private readonly Dictionary<char, TrieNode> _letterToNode = new Dictionary<char, TrieNode>();
        private bool _isEmptyWordIncluded;
    
        public PrefixSearchableSet(IEnumerable<string> words = null)
        {
            if (words is null) return;
            foreach (string word in words)
            {
                AddWord(word);
            }
        }
    
        public void AddWord(string word)
        {
            if (word is null) return;
    
            if (word is "") _isEmptyWordIncluded = true;
    
            else
            {
                TrieNode node = FindOrAdd(_letterToNode, word[0]);
                foreach (char c in word.Skip(1))
                {
                    node = FindOrAdd(node.Children, c);
                }
    
                node.Word = word;
            }
        }
    
        public List<string> GetWords(string prefix)
        {
            List<string> words = new List<string>();
    
            if (prefix is null) return words;
    
            if (prefix is "")
            {
                if (_isEmptyWordIncluded) words.Add("");
                foreach (TrieNode trieNode in _letterToNode.Values)
                {
                    trieNode.CollectWords(words);
                }
                return words;
            }
    
            _letterToNode.TryGetValue(prefix[0], out TrieNode node);
            foreach (char c in prefix.Skip(1))
            {
                if (node is null) break;
                node.Children.TryGetValue(c, out node);
            }
            node?.CollectWords(words);
    
            return words;
        }
    
        private static TrieNode FindOrAdd(Dictionary<char, TrieNode> letterToNode, char key)
        {
            if (letterToNode.TryGetValue(key, out TrieNode node)) return node;
            return letterToNode[key] = new TrieNode();
        }
    
        private class TrieNode
        {
            public Dictionary<char, TrieNode> Children { get; } = new Dictionary<char, TrieNode>();
    
            public string Word { get; set; }
    
            public void CollectWords(List<string> words)
            {
                if (Word != null) words.Add(Word);
                foreach (TrieNode child in Children.Values)
                {
                    child.CollectWords(words);
                }
            }
        }
    }
    
    公共类PrefixSearchableSet
    {
    专用只读词典_letttonode=新词典();
    私人住宅不包括在内;
    公共PrefixSearchableSet(IEnumerable words=null)
    {
    如果(文字为空)返回;
    foreach(单词中的字符串)
    {
    AddWord(word);
    }
    }
    公共无效添加字(字符串字)
    {
    如果(字为空)返回;
    如果(单词为“”)\u ismptywordincluded=true;
    其他的
    {
    三节点节点=FindOrAdd(_letttonode,word[0]);
    foreach(word.Skip(1)中的字符c)
    {
    node=findorad(node.Children,c);
    }
    node.Word=Word;
    }
    }
    公共列表GetWords(字符串前缀)
    {
    列表单词=新列表();
    如果(前缀为空)返回单词;
    if(前缀为“”)
    {
    如果(_ismptywordinclude)字,加上(“”);
    foreach(三元代码三元代码中的三元代码字母代码值)
    {
    三部曲。收集单词(单词);
    }
    返回单词;
    }
    _letterToNode.TryGetValue(前缀[0],输出三节点);
    foreach(前缀中的字符c.Skip(1))
    {
    如果(节点为空)中断;
    node.Children.TryGetValue(c,out节点);
    }
    节点?.collectionwords(words);
    返回单词;
    }
    专用静态三元组FindOrAdd(字典letttonode,char键)
    {
    if(letterToNode.TryGetValue(key,out三节点))返回节点;
    return letternode[键]=新的三节点();
    }
    私有类三节点
    {
    公共字典子项{get;}=new Dictionary();
    公共字符串字{get;set;}
    公共词(列表词)
    {
    如果(单词!=null)单词。添加(单词);
    foreach(儿童中的三元组儿童。值)
    {
    儿童词汇;
    }
    }
    }
    }
    
    +1回答得很好!我记不起它的确切名字了——特里亚!