代码之家  ›  专栏  ›  技术社区  ›  JasCav

按.NET中键/值对的位置随机访问(c)

  •  1
  • JasCav  · 技术社区  · 15 年前

    我目前正在开发一个程序,它使用C的字典容器(特别是SortedDictionary)。这个容器对于我的目的非常有效,除了一个特定的案例,因为我需要随机访问。具体来说,我正在使用伪随机数生成器生成一个随机位置,我需要能够访问SortedDictionary中的该值。在这种情况下,我没有键值。

    我可能会切换到一个可以解决这个问题的列表,但是会在算法的其余部分产生问题,其中sortedDictionary工作得相当好。任何建议/解决方案都将不胜感激。

    我目前正在开发Visual Studio 2005。

    谢谢您。

    5 回复  |  直到 15 年前
        1
  •  2
  •   Richard Berg    15 年前
        public TValue GetRandomElement<TKey, TValue>(SortedDictionary<TKey, TValue> dict)
        {
            Random randGen = new Random();
            int randIndex = randGen.Next(dict.Values.Count);
            int i = 0;
            foreach (TValue value in dict.Values)
            {
                if (i++ == randIndex)
                    return value;
            }
    
            // this shouldn't happen unless I have a bug above or you are accessing the dictionary from multiple threads
            return default(TValue);
        }
    

    盲目枚举ValueCollection并不是世界上最有效的事情。但它能完成任务。如果在您的场景中这是一个频繁的操作,那么您应该考虑一个混合的数据结构,它具有字典查找和随机访问所需的性能特征。

        2
  •  4
  •   eulerfx    15 年前

    您可以使用SortedList,它有一个值集合,您可以通过一个整数索引访问该集合。

        3
  •  1
  •   Fredrik Mörk    15 年前

    Linq可以为您这样做:

    int n = GetRandomIndex();
    object item = dictionary.ElementAt(n).Value;
    
        4
  •  0
  •   Stephan Eggermont    15 年前

    您没有提供足够的信息来提出解决方案。有多少个元素,你多久做一次,你有内存/速度限制吗?btree、sortedList、在sortedDictionary中插入特殊节点都是有用的

        5
  •  0
  •   Joel    15 年前

    随机拉一把钥匙行吗?

    var randValue = myDictionary.Values.ToList()[myRandomInt];
    

    编辑:

    似乎keys集合和values集合都是IEnumerable,因此不能使用[]运算符。这似乎是最好的。

    编辑:

    没有LINQ…可能很贵,但您可以复制到数组,然后在索引处提取值

    System.Collections.Generic.KeyValuePair<string, int>[] dictCopy = new System.Collections.Generic.KeyValuePair<string, int>[myDictionary.Count];
    myDictionary.CopyTo(dictCopy, 0);
    var randValue = dictCopy[myRandomInt].Value;