简体   繁体   English

在字典中查找数字的最接近的下键

[英]Finding closest lower key of a number in a dictionary

I have a Dictionary; 我有一本字典;

Dictionary<int, float> delta = new Dictionary<int, float>();

which contains: 其中包含:

0,  45,2345
7,  25,3556
18, 23,2334

How can i find the value of the closest, lower key to a number? 如何找到最接近数字的下键?

Imagine I have the number 16, id like to find the value of key 7. Same for 4, id like the value of key 0. 想象一下,我有数字16,id喜欢找到键7的值。对于4,id一样喜欢键0的值。

Preferably i'd also like the fastest way to do this, since i have to run the operation several million times. 最好我也想以最快的方式做到这一点,因为我必须运行数百万次操作。

I use C#, .NET 4. 我使用C#、. NET 4。

I suggest using sorted list instead of dictionary , eg 我建议使用排序列表而不是字典 ,例如

  List<Tuple<int, float>> delta = new List<Tuple<int, float>>() {
    new Tuple<int, float>(0, 45.2345F),
    new Tuple<int, float>(7, 25.3556F),
    new Tuple<int, float>(18, 23.2334F),
  };

  // Sort the list 
  delta.Sort((left, right) => left.Item1.CompareTo(right.Item1));

  // ... And binary search then
  int index = delta.BinarySearch(new Tuple<int, float>(16, 0.0F),
    Comparer<Tuple<int, float>>.Create(
      (left, right) => left.Item1.CompareTo(right.Item1)));

  if (index < 0) // If there's not exact match
    index = ~index - 1; // - 1 - ...then return low bound
  else           // in case of exact match
    index -= 1;  // -= 1 ... return low bound as well

  ...
  // Test: "(7, 25.3556)"
  Console.Write(delta[index].ToString()); 

Please note, that you can well have index == -1 in case that there're no items lower than the target 请注意,如果没有低于目标的项目 ,您可以将index == -1

You can filters the keys keeping only the lowers, then gets the max key: 您可以过滤键,只保留较低的键,然后获得最大键:

Dictionary<int, float> delta = new Dictionary<int, float>();
var key = 16;

var maxKey = delta.Keys.Where(k => k < key).Max();
var value = delta[maxKey];

However, as noted in the comments a better approach is use classes like SortedDictionary<> or SortedList<> . 但是,如注释中所述,更好的方法是使用SortedDictionary<>SortedList<>类的类。

If all add/remove operations runs first, and later only searches are performed a solution can be convert the keys to array ( O(N) ) and use Array.BinarySearch() method ( O(log N) ): 如果所有添加/删除操作先运行,然后再执行仅搜索,则可以将键转换为数组( O(N) )并使用Array.BinarySearch()方法( O(log N) ):

SortedDictionary<int, float> sortedDict = new SortedDictionary<int, float>();

// Add-Remove operations

var keys = sortedDict.Keys.ToArray();

// Search operations

int maxKey = Array.BinarySearch(keys, key);
float value = maxIndex >= 0 ? sortedDict[maxKey] : sortedDict[~maxIndex - 1]; 

This should give you what you want 这应该给你你想要的

List<Store> list = new List<Store> { new Store() { Number = 0, Number2 = 452345F }, new Store() { Number = 7, Number2 = 253556F }
        , new Store() { Number = 18, Number2 = 232334F }};
int number = 16;

var closest = list.Aggregate((x, y) => Math.Abs(x.Number - number) < Math.Abs(y.Number - number) ? x : y);

Console.WriteLine(closest.Number2);

class Store
{
    public int Number { get; set; }
    public float Number2 { get; set; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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