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

时间:2016-02-25 15:29:31

标签: c# dictionary

我有一个词典;

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

包含:

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

如何找到最接近的低位键的值?

想象一下,我有16号,id喜欢找到键7的值。 4相同,id类似于键0的值。

最好我也喜欢最快的方式,因为我必须运行数百万次。

我使用C#,.NET 4。

3 个答案:

答案 0 :(得分:3)

我建议使用排序列表而不是词典,例如

  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()); 

请注意,如果没有项目低于目标

,您可以拥有index == -1

答案 1 :(得分:1)

您可以过滤掉只保留下限的键,然后获取最大键:

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

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

但是,如评论中所述,更好的方法是使用SortedDictionary<>SortedList<>等类。

如果所有添加/删除操作都先运行,以后只执行搜索,则解决方案可以将密钥转换为数组( O(N))并使用Array.BinarySearch()方法(< strong> 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]; 

答案 2 :(得分:-3)

这可以给你你想要的东西

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; }
}