最便宜的方法来获取具有最低键值的键值对?

时间:2012-06-08 14:30:04

标签: c# collections

我想要一个集合,它将浮点数的键值对存储到整数中(浮点数是键)。然后我想找到具有最小数字的键值对。所以,我基本上想要使用最低的关联浮点值来获取int值。

也许是一个集合,它根据键保持它们的顺序,并允许我索引它以便在索引0抓取对象是合适的?我不知道从哪里开始寻找这个。

2 个答案:

答案 0 :(得分:9)

您可以尝试SortedDictionary。如果你打电话给.Keys,你将得到一个有序的密钥集合。然后,您可以使用LINQ .First()函数获取集合中的第一个键,例如:

var mySortedDictionary = new SortedDictionary<float, int>();

// ...
// Add some values to dictionary
// ...

// Note, you will need the System.Linq namespace for First()
float firstKey = mySortedDictionary.Keys.First();
int firstValue = mySortedDictionary[firstKey];
// If you just need the value:
int firstValue2 = mySortedDictionary.Values.First();

如果你需要获得第一个或最后一个以外的密钥,你可以使用LINQ .ToArray().ToList()函数返回一个可索引的数组或列表,如下所示:

float[] indexableKeys = mySortedDictionary.Keys.ToArray();
int[] indexableValues = mySortedDictionary.Values.ToArray();

此外,以下代码将遍历集合并按排序顺序为您提供所有KeyValuePairs:

foreach (var pair in mySortedDictionary)
{
    int key = pair.Key;
    // Do stuff with key...
    object value = pair.Value;
    // Do stuff with value...
}

作为替代方案,您还可以使用SortedList,其中 可转位。要使用它,您只需要以下代码:

var mySortedList = new SortedList<float, int>();
// ...
// Add some values to sortedlist
// ...
int firstValue = mySortedList.Values[0];

注意:我没有机会对这些中的任何一个进行基准测试,所以我不确定哪个会表现得更好。使用已排序的集合肯定比常规集合具有更多的开销。如果您只需要知道哪个键是第一个键,那么最好创建一个包含Dictionary和私有字段private float first;的自定义类,该字段存储哪个键是第一个键。当您添加到该类时,它会将KeyValuePair添加到字典中,并检查该键是否小于您的first变量(或者如果字典中没有键)。如果是,则将first设置为新密钥。删除值时,再次将其从“词典”中删除。如果密钥等于您的first值,那么您需要对Dictionary.Keys集合进行排序并首先找到新的。这可能是最好的,但你必须自己写课。

注意: 在做了一些基准测试之后,我发现SortedDictionary移除速度更快,但SortedList更快,可以通过键添加和索引。这是通过填充a来完成的。具有1,000,000个keyValue对的常规字典(键被洗牌以便以随机顺序输入)。然后我:

  • 将这些对中的每一对添加到两个已排序的集合
  • 对两个已排序集合中的每个键执行查找
  • 通过调用两个已排序集合上的删除(密钥)
  • 删除每对

SortedList在添加或索引时的速度大约是其两倍,但删除每个元素的时间大约是其1000倍。

答案 1 :(得分:0)

当然,您可以使用任何完全排序的数据结构。但“完全排序”的部分当然有一些开销。

如果只检索最低密钥,那么“priority queue”通常是最好的数据结构。已经提出了一个适当的问题here